Commit 225664550f3cd23b4c26a9aded828cf39c2ec0eb
1 parent
767cd902
实现短信通过redis stream异步发送,实现短信callback处理
Showing
53 changed files
with
819 additions
and
434 deletions
sql/sms.sql
| @@ -12,7 +12,6 @@ CREATE TABLE `sms_channel` | @@ -12,7 +12,6 @@ CREATE TABLE `sms_channel` | ||
| 12 | `code` varchar(50) NOT NULL COMMENT '编码(来自枚举类 阿里、华为、七牛等)', | 12 | `code` varchar(50) NOT NULL COMMENT '编码(来自枚举类 阿里、华为、七牛等)', |
| 13 | `api_key` varchar(100) NOT NULL COMMENT '账号id', | 13 | `api_key` varchar(100) NOT NULL COMMENT '账号id', |
| 14 | `api_secret` varchar(100) NOT NULL COMMENT '账号秘钥', | 14 | `api_secret` varchar(100) NOT NULL COMMENT '账号秘钥', |
| 15 | - `had_callback` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否拥有回调函数', | ||
| 16 | `callback_url` varchar(100) NOT NULL default '' COMMENT '回调请求路径', | 15 | `callback_url` varchar(100) NOT NULL default '' COMMENT '回调请求路径', |
| 17 | `api_signature_id` varchar(100) NOT NULL COMMENT '实际渠道签名唯一标识', | 16 | `api_signature_id` varchar(100) NOT NULL COMMENT '实际渠道签名唯一标识', |
| 18 | `name` varchar(50) NOT NULL COMMENT '名称', | 17 | `name` varchar(50) NOT NULL COMMENT '名称', |
| @@ -61,7 +60,7 @@ CREATE TABLE `sms_template` | @@ -61,7 +60,7 @@ CREATE TABLE `sms_template` | ||
| 61 | ) ENGINE = InnoDB | 60 | ) ENGINE = InnoDB |
| 62 | AUTO_INCREMENT = 1 | 61 | AUTO_INCREMENT = 1 |
| 63 | DEFAULT CHARSET = utf8mb4 COMMENT ='短信模板'; | 62 | DEFAULT CHARSET = utf8mb4 COMMENT ='短信模板'; |
| 64 | - | 63 | +/* |
| 65 | -- ---------------------------- | 64 | -- ---------------------------- |
| 66 | -- Table structure for sms_query_log | 65 | -- Table structure for sms_query_log |
| 67 | -- ---------------------------- | 66 | -- ---------------------------- |
| @@ -73,7 +72,7 @@ CREATE TABLE `sms_query_log` | @@ -73,7 +72,7 @@ CREATE TABLE `sms_query_log` | ||
| 73 | `channel_code` varchar(50) NOT NULL COMMENT '短信渠道编码(来自枚举类)', | 72 | `channel_code` varchar(50) NOT NULL COMMENT '短信渠道编码(来自枚举类)', |
| 74 | `channel_id` bigint(20) NOT NULL COMMENT '短信渠道id', | 73 | `channel_id` bigint(20) NOT NULL COMMENT '短信渠道id', |
| 75 | `template_code` varchar(50) NOT NULL COMMENT '渠道编码', | 74 | `template_code` varchar(50) NOT NULL COMMENT '渠道编码', |
| 76 | - `phones` varchar(2000) NOT NULL COMMENT '手机号(数组json字符串)', | 75 | + `phone` char(11) NOT NULL COMMENT '手机号', |
| 77 | `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容', | 76 | `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容', |
| 78 | `send_result_param` varchar(200) NOT NULL DEFAULT '' COMMENT '查询短信发送结果的参数', | 77 | `send_result_param` varchar(200) NOT NULL DEFAULT '' COMMENT '查询短信发送结果的参数', |
| 79 | `send_status` tinyint(1) NOT NULL DEFAULT 2 COMMENT '发送状态(0本地异步中 1发送请求失败 2发送请求成功)', | 78 | `send_status` tinyint(1) NOT NULL DEFAULT 2 COMMENT '发送状态(0本地异步中 1发送请求失败 2发送请求成功)', |
| @@ -84,24 +83,26 @@ CREATE TABLE `sms_query_log` | @@ -84,24 +83,26 @@ CREATE TABLE `sms_query_log` | ||
| 84 | PRIMARY KEY (`id`) USING BTREE | 83 | PRIMARY KEY (`id`) USING BTREE |
| 85 | ) ENGINE = InnoDB | 84 | ) ENGINE = InnoDB |
| 86 | AUTO_INCREMENT = 1 | 85 | AUTO_INCREMENT = 1 |
| 87 | - DEFAULT CHARSET = utf8mb4 COMMENT ='短信请求日志'; | 86 | + DEFAULT CHARSET = utf8mb4 COMMENT ='短信请求日志';*/ |
| 88 | 87 | ||
| 89 | -- ---------------------------- | 88 | -- ---------------------------- |
| 90 | -- Table structure for sms_log | 89 | -- Table structure for sms_log |
| 91 | -- ---------------------------- | 90 | -- ---------------------------- |
| 92 | -DROP TABLE IF EXISTS `sms_send_log`; | ||
| 93 | -CREATE TABLE `sms_send_log` | 91 | +DROP TABLE IF EXISTS `sms_query_log`; |
| 92 | +CREATE TABLE `sms_query_log` | ||
| 94 | ( | 93 | ( |
| 95 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号', | 94 | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增编号', |
| 95 | + `api_id` varchar(100) NOT NULL COMMENT '第三方唯一标识', | ||
| 96 | `channel_code` varchar(50) NOT NULL COMMENT '短信渠道编码(来自枚举类)', | 96 | `channel_code` varchar(50) NOT NULL COMMENT '短信渠道编码(来自枚举类)', |
| 97 | `channel_id` bigint(20) NOT NULL COMMENT '短信渠道id', | 97 | `channel_id` bigint(20) NOT NULL COMMENT '短信渠道id', |
| 98 | `template_code` varchar(50) NOT NULL COMMENT '渠道编码', | 98 | `template_code` varchar(50) NOT NULL COMMENT '渠道编码', |
| 99 | - `query_log_id` bigint(20) NOT NULL COMMENT '请求日志id', | ||
| 100 | `phone` char(11) NOT NULL COMMENT '手机号', | 99 | `phone` char(11) NOT NULL COMMENT '手机号', |
| 101 | `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容', | 100 | `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '内容', |
| 101 | + `send_status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '发送状态 详情见:SmsSendStatusEnum', | ||
| 102 | `remark` varchar(200) DEFAULT NULL COMMENT '备注', | 102 | `remark` varchar(200) DEFAULT NULL COMMENT '备注', |
| 103 | - `success` tinyint(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', | ||
| 104 | - `send_time` datetime DEFAULT NULL COMMENT '创建时间', | 103 | + `create_by` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者', |
| 104 | + `create_time` datetime DEFAULT NULL COMMENT '创建时间', | ||
| 105 | + `send_time` datetime DEFAULT NULL COMMENT '发送时间', | ||
| 105 | PRIMARY KEY (`id`) USING BTREE | 106 | PRIMARY KEY (`id`) USING BTREE |
| 106 | ) ENGINE = InnoDB | 107 | ) ENGINE = InnoDB |
| 107 | AUTO_INCREMENT = 1 | 108 | AUTO_INCREMENT = 1 |
src/main/java/cn/iocoder/dashboard/DashboardApplication.java
| 1 | -//package cn.iocoder.dashboard; | ||
| 2 | -// | ||
| 3 | -//import de.codecentric.boot.admin.server.config.EnableAdminServer; | ||
| 4 | -//import org.springframework.boot.SpringApplication; | ||
| 5 | -//import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| 6 | -// | ||
| 7 | -//@SpringBootApplication | ||
| 8 | -//@EnableAdminServer | ||
| 9 | -//public class DashboardApplication { | ||
| 10 | -// | ||
| 11 | -// public static void main(String[] args) { | ||
| 12 | -// SpringApplication.run(DashboardApplication.class, args); | ||
| 13 | -// } | ||
| 14 | -// | ||
| 15 | -//} | 1 | +package cn.iocoder.dashboard; |
| 2 | + | ||
| 3 | +import de.codecentric.boot.admin.server.config.EnableAdminServer; | ||
| 4 | +import org.springframework.boot.SpringApplication; | ||
| 5 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
| 6 | + | ||
| 7 | +@SpringBootApplication | ||
| 8 | +@EnableAdminServer | ||
| 9 | +public class DashboardApplication { | ||
| 10 | + | ||
| 11 | + public static void main(String[] args) { | ||
| 12 | + SpringApplication.run(DashboardApplication.class, args); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | +} |
src/main/java/cn/iocoder/dashboard/framework/redis/core/util/RedisStreamUtils.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.redis.core.util; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendMessage; | ||
| 4 | +import org.springframework.data.redis.connection.stream.StreamRecords; | ||
| 5 | +import org.springframework.data.redis.core.RedisTemplate; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * Redis 消息工具类 | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +public class RedisStreamUtils { | ||
| 13 | + | ||
| 14 | + public static final String KEY_SMS_SEND = "stream_sms_send"; | ||
| 15 | + | ||
| 16 | + public static final String GROUP_SMS_SEND = "group_sms_send"; | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * 发送 Redis 消息,基于 Redis pub/sub 实现 | ||
| 20 | + * | ||
| 21 | + * @param redisTemplate Redis 操作模板 | ||
| 22 | + * @param message 消息 | ||
| 23 | + */ | ||
| 24 | + public static void sendChannelMessage(RedisTemplate<String, ?> redisTemplate, SmsSendMessage message) { | ||
| 25 | + | ||
| 26 | + redisTemplate.opsForStream().add(StreamRecords.newRecord().ofObject(message).withStreamKey(KEY_SMS_SEND)); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
src/main/java/cn/iocoder/dashboard/framework/security/config/SecurityConfiguration.java
| @@ -134,6 +134,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | @@ -134,6 +134,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | ||
| 134 | .antMatchers(webProperties.getApiPrefix() + "/system/file/get/**").anonymous() | 134 | .antMatchers(webProperties.getApiPrefix() + "/system/file/get/**").anonymous() |
| 135 | // TODO | 135 | // TODO |
| 136 | .antMatchers("/swagger-ui.html").anonymous() | 136 | .antMatchers("/swagger-ui.html").anonymous() |
| 137 | + .antMatchers("/**").anonymous() | ||
| 137 | .antMatchers("/swagger-resources/**").anonymous() | 138 | .antMatchers("/swagger-resources/**").anonymous() |
| 138 | .antMatchers("/webjars/**").anonymous() | 139 | .antMatchers("/webjars/**").anonymous() |
| 139 | .antMatchers("/*/api-docs").anonymous() | 140 | .antMatchers("/*/api-docs").anonymous() |
src/main/java/cn/iocoder/dashboard/framework/sms/client/AbstractSmsClient.java
| @@ -5,8 +5,6 @@ import cn.iocoder.dashboard.framework.sms.core.SmsResult; | @@ -5,8 +5,6 @@ import cn.iocoder.dashboard.framework.sms.core.SmsResult; | ||
| 5 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; | 5 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | 7 | ||
| 8 | -import java.util.Collection; | ||
| 9 | - | ||
| 10 | /** | 8 | /** |
| 11 | * 抽象短息客户端 | 9 | * 抽象短息客户端 |
| 12 | * | 10 | * |
| @@ -35,12 +33,12 @@ public abstract class AbstractSmsClient implements SmsClient { | @@ -35,12 +33,12 @@ public abstract class AbstractSmsClient implements SmsClient { | ||
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | @Override | 35 | @Override |
| 38 | - public final SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets) { | 36 | + public final SmsResult send(String templateApiId, SmsBody smsBody, String target) { |
| 39 | SmsResult result; | 37 | SmsResult result; |
| 40 | try { | 38 | try { |
| 41 | - beforeSend(templateApiId, smsBody, targets); | ||
| 42 | - result = doSend(templateApiId, smsBody, targets); | ||
| 43 | - afterSend(templateApiId, smsBody, targets, result); | 39 | + beforeSend(templateApiId, smsBody, target); |
| 40 | + result = doSend(templateApiId, smsBody, target); | ||
| 41 | + afterSend(templateApiId, smsBody, target, result); | ||
| 44 | } catch (Exception e) { | 42 | } catch (Exception e) { |
| 45 | // exception handle | 43 | // exception handle |
| 46 | log.debug(e.getMessage(), e); | 44 | log.debug(e.getMessage(), e); |
| @@ -54,16 +52,16 @@ public abstract class AbstractSmsClient implements SmsClient { | @@ -54,16 +52,16 @@ public abstract class AbstractSmsClient implements SmsClient { | ||
| 54 | * | 52 | * |
| 55 | * @param templateApiId 短信模板唯一标识 | 53 | * @param templateApiId 短信模板唯一标识 |
| 56 | * @param smsBody 消息内容 | 54 | * @param smsBody 消息内容 |
| 57 | - * @param targets 发送对象列表 | 55 | + * @param targetPhone 发送对象手机号 |
| 58 | * @return 短信发送结果 | 56 | * @return 短信发送结果 |
| 59 | * @throws Exception 调用发送失败,抛出异常 | 57 | * @throws Exception 调用发送失败,抛出异常 |
| 60 | */ | 58 | */ |
| 61 | - protected abstract SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception; | 59 | + protected abstract SmsResult doSend(String templateApiId, SmsBody smsBody, String targetPhone) throws Exception; |
| 62 | 60 | ||
| 63 | - protected void beforeSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception { | 61 | + protected void beforeSend(String templateApiId, SmsBody smsBody, String targetPhone) throws Exception { |
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | - protected void afterSend(String templateApiId, SmsBody smsBody, Collection<String> targets, SmsResult result) throws Exception { | 64 | + protected void afterSend(String templateApiId, SmsBody smsBody, String targetPhone, SmsResult result) throws Exception { |
| 67 | } | 65 | } |
| 68 | 66 | ||
| 69 | } | 67 | } |
src/main/java/cn/iocoder/dashboard/framework/sms/client/AliyunSmsClient.java deleted
| 1 | -package cn.iocoder.dashboard.framework.sms.client; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.date.DateUtil; | ||
| 4 | -import cn.hutool.core.util.ArrayUtil; | ||
| 5 | -import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 6 | -import cn.iocoder.dashboard.framework.sms.core.SmsResult; | ||
| 7 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 8 | -import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; | ||
| 9 | -import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum; | ||
| 10 | -import com.aliyuncs.DefaultAcsClient; | ||
| 11 | -import com.aliyuncs.IAcsClient; | ||
| 12 | -import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest; | ||
| 13 | -import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse; | ||
| 14 | -import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; | ||
| 15 | -import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; | ||
| 16 | -import com.aliyuncs.exceptions.ClientException; | ||
| 17 | -import com.aliyuncs.http.MethodType; | ||
| 18 | -import com.aliyuncs.profile.DefaultProfile; | ||
| 19 | -import com.aliyuncs.profile.IClientProfile; | ||
| 20 | -import lombok.extern.slf4j.Slf4j; | ||
| 21 | - | ||
| 22 | -import java.util.ArrayList; | ||
| 23 | -import java.util.Collection; | ||
| 24 | -import java.util.List; | ||
| 25 | - | ||
| 26 | -/** | ||
| 27 | - * 阿里短信实现类 | ||
| 28 | - * | ||
| 29 | - * @author zzf | ||
| 30 | - * @date 2021/1/25 14:17 | ||
| 31 | - */ | ||
| 32 | -@Slf4j | ||
| 33 | -public class AliyunSmsClient extends AbstractSmsClient implements NeedQuerySendResultSmsClient { | ||
| 34 | - | ||
| 35 | - private static final String OK = "OK"; | ||
| 36 | - | ||
| 37 | - private static final String PRODUCT = "Dysmsapi"; | ||
| 38 | - | ||
| 39 | - private static final String DOMAIN = "dysmsapi.aliyuncs.com"; | ||
| 40 | - | ||
| 41 | - private static final String ENDPOINT = "cn-hangzhou"; | ||
| 42 | - | ||
| 43 | - private final IAcsClient acsClient; | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * 构造阿里云短信发送处理 | ||
| 47 | - * | ||
| 48 | - * @param channelVO 阿里云短信配置 | ||
| 49 | - */ | ||
| 50 | - public AliyunSmsClient(SmsChannelProperty channelVO) { | ||
| 51 | - super(channelVO); | ||
| 52 | - | ||
| 53 | - String accessKeyId = channelVO.getApiKey(); | ||
| 54 | - String accessKeySecret = channelVO.getApiSecret(); | ||
| 55 | - | ||
| 56 | - IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, accessKeyId, accessKeySecret); | ||
| 57 | - DefaultProfile.addEndpoint(ENDPOINT, PRODUCT, DOMAIN); | ||
| 58 | - | ||
| 59 | - acsClient = new DefaultAcsClient(profile); | ||
| 60 | - } | ||
| 61 | - | ||
| 62 | - @Override | ||
| 63 | - public SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) throws Exception { | ||
| 64 | - SendSmsRequest request = new SendSmsRequest(); | ||
| 65 | - request.setSysMethod(MethodType.POST); | ||
| 66 | - request.setPhoneNumbers(ArrayUtil.join(targets, ",")); | ||
| 67 | - request.setSignName(channelVO.getApiSignatureId()); | ||
| 68 | - request.setTemplateCode(templateApiId); | ||
| 69 | - request.setTemplateParam(smsBody.getParamsStr()); | ||
| 70 | - SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); | ||
| 71 | - | ||
| 72 | - boolean success = OK.equals(sendSmsResponse.getCode()); | ||
| 73 | - if (!success) { | ||
| 74 | - log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage()); | ||
| 75 | - } | ||
| 76 | - return new SmsResult() | ||
| 77 | - .setSuccess(success) | ||
| 78 | - .setMessage(sendSmsResponse.getMessage()) | ||
| 79 | - .setCode(sendSmsResponse.getCode()) | ||
| 80 | - .setApiId(sendSmsResponse.getBizId()) | ||
| 81 | - .setSendResultParam(sendSmsResponse.getBizId()); | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - | ||
| 85 | - @Override | ||
| 86 | - public List<SmsResultDetail> getSmsSendResult(String param) throws ClientException { | ||
| 87 | - QuerySendDetailsRequest querySendDetailsRequest = new QuerySendDetailsRequest(); | ||
| 88 | - querySendDetailsRequest.setBizId(param); | ||
| 89 | - // TODO FROM 芋艿 to zzf:发送完之后,基于短信平台回调,去更新回执状态。短信发送是否成功,和最终用户收到,是两个维度。这块有困惑,可以微信,我给个截图哈。 DONE | ||
| 90 | - QuerySendDetailsResponse acsResponse = acsClient.getAcsResponse(querySendDetailsRequest); | ||
| 91 | - List<SmsResultDetail> resultDetailList = new ArrayList<>(Integer.parseInt(acsResponse.getTotalCount())); | ||
| 92 | - acsResponse.getSmsSendDetailDTOs().forEach(s -> { | ||
| 93 | - SmsResultDetail resultDetail = new SmsResultDetail(); | ||
| 94 | - resultDetail.setSendTime(DateUtil.parseDateTime(s.getSendDate())); | ||
| 95 | - resultDetail.setMessage(s.getContent()); | ||
| 96 | - resultDetail.setPhone(s.getPhoneNum()); | ||
| 97 | - resultDetail.setSendStatus(statusConvert(s.getSendStatus())); | ||
| 98 | - resultDetailList.add(resultDetail); | ||
| 99 | - }); | ||
| 100 | - return resultDetailList; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - private int statusConvert(Long aliSendStatus) { | ||
| 104 | - if (aliSendStatus == 1L) { | ||
| 105 | - return SmsSendStatusEnum.SEND_SUCCESS.getStatus(); | ||
| 106 | - } | ||
| 107 | - if (aliSendStatus == 2L) { | ||
| 108 | - return SmsSendStatusEnum.SEND_FAIL.getStatus(); | ||
| 109 | - } | ||
| 110 | - return SmsSendStatusEnum.WAITING.getStatus(); | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | -} |
src/main/java/cn/iocoder/dashboard/framework/sms/client/HadCallbackSmsClient.java deleted
| 1 | -package cn.iocoder.dashboard.framework.sms.client; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 4 | - | ||
| 5 | -import javax.servlet.ServletRequest; | ||
| 6 | -import java.io.UnsupportedEncodingException; | ||
| 7 | -import java.util.List; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 需要发送请求获取短信发送结果的短信客户端 | ||
| 11 | - * | ||
| 12 | - * @author zzf | ||
| 13 | - * @date 2021/3/4 17:20 | ||
| 14 | - */ | ||
| 15 | -public interface HadCallbackSmsClient { | ||
| 16 | - | ||
| 17 | - /** | ||
| 18 | - * 获取短信发送结果 | ||
| 19 | - * | ||
| 20 | - * @param request 请求 | ||
| 21 | - * @return 短信发送结果 | ||
| 22 | - */ | ||
| 23 | - List<SmsResultDetail> getSmsSendResult(ServletRequest request) throws Exception; | ||
| 24 | - | ||
| 25 | -} |
src/main/java/cn/iocoder/dashboard/framework/sms/client/NeedQuerySendResultSmsClient.java deleted
| 1 | -package cn.iocoder.dashboard.framework.sms.client; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 4 | -import com.aliyuncs.exceptions.ClientException; | ||
| 5 | - | ||
| 6 | -import java.util.List; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 需要发送请求获取短信发送结果的短信客户端 | ||
| 10 | - * | ||
| 11 | - * @author zzf | ||
| 12 | - * @date 2021/3/4 17:20 | ||
| 13 | - */ | ||
| 14 | -public interface NeedQuerySendResultSmsClient { | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 获取短信发送结果 | ||
| 18 | - * | ||
| 19 | - * @param param 参数 | ||
| 20 | - * @return 短信发送结果 | ||
| 21 | - */ | ||
| 22 | - List<SmsResultDetail> getSmsSendResult(String param) throws Exception; | ||
| 23 | - | ||
| 24 | -} |
src/main/java/cn/iocoder/dashboard/framework/sms/client/SmsClient.java
| @@ -4,8 +4,7 @@ import cn.iocoder.dashboard.framework.sms.core.SmsBody; | @@ -4,8 +4,7 @@ import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; | 4 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; |
| 6 | 6 | ||
| 7 | -import java.util.Collection; | ||
| 8 | -import java.util.List; | 7 | +import javax.servlet.ServletRequest; |
| 9 | 8 | ||
| 10 | /** | 9 | /** |
| 11 | * 短信父接口 | 10 | * 短信父接口 |
| @@ -23,9 +22,15 @@ public interface SmsClient { | @@ -23,9 +22,15 @@ public interface SmsClient { | ||
| 23 | * @param targets 发送对象列表 | 22 | * @param targets 发送对象列表 |
| 24 | * @return 短信发送结果 | 23 | * @return 短信发送结果 |
| 25 | */ | 24 | */ |
| 26 | - SmsResult send(String templateApiId, SmsBody smsBody, Collection<String> targets); | 25 | + SmsResult send(String templateApiId, SmsBody smsBody, String targets); |
| 27 | 26 | ||
| 28 | 27 | ||
| 29 | - //List<SmsResultDetail> getSmsSendResult(String jsonObjectParam); | 28 | + /** |
| 29 | + * 短信发送回调请求处理 | ||
| 30 | + * | ||
| 31 | + * @param request 请求 | ||
| 32 | + * @return 短信发送结果 | ||
| 33 | + */ | ||
| 34 | + SmsResultDetail smsSendCallbackHandle(ServletRequest request) throws Exception; | ||
| 30 | 35 | ||
| 31 | } | 36 | } |
| 32 | \ No newline at end of file | 37 | \ No newline at end of file |
src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/ali/AliyunSmsClient.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.framework.sms.client.impl.ali; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | +import cn.hutool.core.date.DateUtil; | ||
| 5 | +import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | ||
| 6 | +import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 7 | +import cn.iocoder.dashboard.framework.sms.core.SmsResult; | ||
| 8 | +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 9 | +import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; | ||
| 10 | +import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum; | ||
| 11 | +import cn.iocoder.dashboard.util.json.JsonUtils; | ||
| 12 | +import com.aliyuncs.DefaultAcsClient; | ||
| 13 | +import com.aliyuncs.IAcsClient; | ||
| 14 | +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; | ||
| 15 | +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; | ||
| 16 | +import com.aliyuncs.http.MethodType; | ||
| 17 | +import com.aliyuncs.profile.DefaultProfile; | ||
| 18 | +import com.aliyuncs.profile.IClientProfile; | ||
| 19 | +import com.fasterxml.jackson.core.type.TypeReference; | ||
| 20 | +import lombok.extern.slf4j.Slf4j; | ||
| 21 | + | ||
| 22 | +import javax.servlet.ServletRequest; | ||
| 23 | +import java.io.BufferedReader; | ||
| 24 | +import java.io.InputStreamReader; | ||
| 25 | +import java.util.Date; | ||
| 26 | +import java.util.HashMap; | ||
| 27 | +import java.util.List; | ||
| 28 | +import java.util.Map; | ||
| 29 | + | ||
| 30 | +/** | ||
| 31 | + * 阿里短信实现类 | ||
| 32 | + * | ||
| 33 | + * @author zzf | ||
| 34 | + * @date 2021/1/25 14:17 | ||
| 35 | + */ | ||
| 36 | +@Slf4j | ||
| 37 | +public class AliyunSmsClient extends AbstractSmsClient { | ||
| 38 | + | ||
| 39 | + private static final String OK = "OK"; | ||
| 40 | + | ||
| 41 | + private static final String PRODUCT = "Dystopi"; | ||
| 42 | + | ||
| 43 | + private static final String DOMAIN = "dysmsapi.aliyuncs.com"; | ||
| 44 | + | ||
| 45 | + private static final String ENDPOINT = "cn-hangzhou"; | ||
| 46 | + | ||
| 47 | + private final IAcsClient acsClient; | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * 构造阿里云短信发送处理 | ||
| 51 | + * | ||
| 52 | + * @param channelVO 阿里云短信配置 | ||
| 53 | + */ | ||
| 54 | + public AliyunSmsClient(SmsChannelProperty channelVO) { | ||
| 55 | + super(channelVO); | ||
| 56 | + | ||
| 57 | + String accessKeyId = channelVO.getApiKey(); | ||
| 58 | + String accessKeySecret = channelVO.getApiSecret(); | ||
| 59 | + | ||
| 60 | + IClientProfile profile = DefaultProfile.getProfile(ENDPOINT, accessKeyId, accessKeySecret); | ||
| 61 | + DefaultProfile.addEndpoint(ENDPOINT, PRODUCT, DOMAIN); | ||
| 62 | + | ||
| 63 | + acsClient = new DefaultAcsClient(profile); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + @Override | ||
| 67 | + public SmsResult doSend(String templateApiId, SmsBody smsBody, String targetPhone) throws Exception { | ||
| 68 | + SendSmsRequest request = new SendSmsRequest(); | ||
| 69 | + request.setSysMethod(MethodType.POST); | ||
| 70 | + request.setPhoneNumbers(targetPhone); | ||
| 71 | + request.setSignName(channelVO.getApiSignatureId()); | ||
| 72 | + request.setTemplateCode(templateApiId); | ||
| 73 | + request.setTemplateParam(smsBody.getParamsStr()); | ||
| 74 | + SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); | ||
| 75 | + | ||
| 76 | + boolean success = OK.equals(sendSmsResponse.getCode()); | ||
| 77 | + if (!success) { | ||
| 78 | + log.debug("send fail[code={}, message={}]", sendSmsResponse.getCode(), sendSmsResponse.getMessage()); | ||
| 79 | + } | ||
| 80 | + return new SmsResult() | ||
| 81 | + .setSuccess(success) | ||
| 82 | + .setMessage(sendSmsResponse.getMessage()) | ||
| 83 | + .setCode(sendSmsResponse.getCode()) | ||
| 84 | + .setApiId(sendSmsResponse.getBizId()); | ||
| 85 | + } | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * [{ | ||
| 89 | + * "send_time" : "2017-08-30 00:00:00", | ||
| 90 | + * "report_time" : "2017-08-30 00:00:00", | ||
| 91 | + * "success" : true, | ||
| 92 | + * "err_msg" : "用户接收成功", | ||
| 93 | + * "err_code" : "DELIVERED", | ||
| 94 | + * "phone_number" : "18612345678", | ||
| 95 | + * "sms_size" : "1", | ||
| 96 | + * "biz_id" : "932702304080415357^0", | ||
| 97 | + * "out_id" : "1184585343" | ||
| 98 | + * }] | ||
| 99 | + * | ||
| 100 | + * @param request 请求 | ||
| 101 | + * @return | ||
| 102 | + * @throws Exception | ||
| 103 | + */ | ||
| 104 | + @Override | ||
| 105 | + public SmsResultDetail smsSendCallbackHandle(ServletRequest request) throws Exception { | ||
| 106 | + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); | ||
| 107 | + String paramStr = reader.readLine(); | ||
| 108 | + List<Map<String, Object>> params = JsonUtils.parseByType(paramStr, new TypeReference<List<Map<String, Object>>>() { | ||
| 109 | + }); | ||
| 110 | + if (CollectionUtil.isNotEmpty(params)) { | ||
| 111 | + Map<String, Object> sendResultParamMap = params.get(0); | ||
| 112 | + return CallbackHelper.of(sendResultParamMap).toResultDetail(); | ||
| 113 | + } | ||
| 114 | + return null; | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * 短信发送回调辅助类 | ||
| 119 | + */ | ||
| 120 | + private static class CallbackHelper { | ||
| 121 | + | ||
| 122 | + private final Map<String, Object> sendResultParamMap; | ||
| 123 | + | ||
| 124 | + private CallbackHelper(Map<String, Object> sendResultParamMap) { | ||
| 125 | + this.sendResultParamMap = sendResultParamMap; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public static CallbackHelper of(Map<String, Object> sendResultParamMap) { | ||
| 129 | + return new CallbackHelper(sendResultParamMap); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + public Integer getSendStatus() { | ||
| 133 | + return ((Boolean) sendResultParamMap.get(CallbackField.SUCCESS)) | ||
| 134 | + ? SmsSendStatusEnum.SEND_SUCCESS.getStatus() | ||
| 135 | + : SmsSendStatusEnum.SEND_FAIL.getStatus(); | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + public String getBizId() { | ||
| 139 | + return sendResultParamMap.get(CallbackField.BIZ_ID).toString(); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + public String getErrMsg() { | ||
| 143 | + return sendResultParamMap.get(CallbackField.ERR_MSG).toString(); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + public String getErrCode() { | ||
| 147 | + return sendResultParamMap.get(CallbackField.ERR_CODE).toString(); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + public Date getSendTime() { | ||
| 151 | + return DateUtil.parseTime(sendResultParamMap.get(CallbackField.SEND_TIME).toString()); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + public String getPhoneNumber() { | ||
| 155 | + return sendResultParamMap.get(CallbackField.PHONE_NUMBER).toString(); | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + public String getOutId() { | ||
| 159 | + return sendResultParamMap.get(CallbackField.OUT_ID).toString(); | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + public SmsResultDetail toResultDetail() { | ||
| 163 | + SmsResultDetail resultDetail = new SmsResultDetail(); | ||
| 164 | + resultDetail.setSendStatus(getSendStatus()); | ||
| 165 | + resultDetail.setApiId(getBizId()); | ||
| 166 | + resultDetail.setSendTime(getSendTime()); | ||
| 167 | + resultDetail.setPhone(getPhoneNumber()); | ||
| 168 | + resultDetail.setMessage(getErrMsg()); | ||
| 169 | + | ||
| 170 | + resultDetail.setCallbackResponseBody(generateSuccessResponseBody()); | ||
| 171 | + return resultDetail; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + /** | ||
| 175 | + * 生成回调成功的返回对象 | ||
| 176 | + */ | ||
| 177 | + private Map<String, Object> generateSuccessResponseBody() { | ||
| 178 | + Map<String, Object> result = new HashMap<>(); | ||
| 179 | + result.put("code", 0); | ||
| 180 | + result.put("msg", "成功"); | ||
| 181 | + return result; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + /** | ||
| 187 | + * 回调接口字段定义 | ||
| 188 | + */ | ||
| 189 | + private interface CallbackField { | ||
| 190 | + //是否成功 boolean | ||
| 191 | + String SUCCESS = "success"; | ||
| 192 | + | ||
| 193 | + //发送时间 | ||
| 194 | + String SEND_TIME = "send_time"; | ||
| 195 | + | ||
| 196 | + //错误信息 | ||
| 197 | + String ERR_MSG = "err_msg"; | ||
| 198 | + | ||
| 199 | + //错误编码 | ||
| 200 | + String ERR_CODE = "err_code"; | ||
| 201 | + | ||
| 202 | + //手机号 | ||
| 203 | + String PHONE_NUMBER = "phone_number"; | ||
| 204 | + | ||
| 205 | + //用户序列号 out_id | ||
| 206 | + String OUT_ID = "out_id"; | ||
| 207 | + | ||
| 208 | + //biz_id 即 apiId 唯一标识 | ||
| 209 | + String BIZ_ID = "biz_id"; | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | +} |
src/main/java/cn/iocoder/dashboard/framework/sms/client/YunpianSmsClient.java renamed to src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/yunpian/YunpianSmsClient.java
| 1 | -package cn.iocoder.dashboard.framework.sms.client; | 1 | +package cn.iocoder.dashboard.framework.sms.client.impl.yunpian; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollectionUtil; | ||
| 3 | import cn.hutool.core.date.DateUtil; | 4 | import cn.hutool.core.date.DateUtil; |
| 4 | import cn.hutool.core.util.CharsetUtil; | 5 | import cn.hutool.core.util.CharsetUtil; |
| 6 | +import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | ||
| 5 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 7 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 6 | import cn.iocoder.dashboard.framework.sms.core.SmsConstants; | 8 | import cn.iocoder.dashboard.framework.sms.core.SmsConstants; |
| 7 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; | 9 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| @@ -14,13 +16,15 @@ import com.yunpian.sdk.YunpianClient; | @@ -14,13 +16,15 @@ import com.yunpian.sdk.YunpianClient; | ||
| 14 | import com.yunpian.sdk.constant.Code; | 16 | import com.yunpian.sdk.constant.Code; |
| 15 | import com.yunpian.sdk.constant.YunpianConstant; | 17 | import com.yunpian.sdk.constant.YunpianConstant; |
| 16 | import com.yunpian.sdk.model.Result; | 18 | import com.yunpian.sdk.model.Result; |
| 17 | -import com.yunpian.sdk.model.SmsBatchSend; | 19 | +import com.yunpian.sdk.model.SmsSingleSend; |
| 18 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| 19 | 21 | ||
| 20 | import javax.servlet.ServletRequest; | 22 | import javax.servlet.ServletRequest; |
| 21 | import java.io.UnsupportedEncodingException; | 23 | import java.io.UnsupportedEncodingException; |
| 22 | import java.net.URLEncoder; | 24 | import java.net.URLEncoder; |
| 23 | -import java.util.*; | 25 | +import java.util.HashMap; |
| 26 | +import java.util.List; | ||
| 27 | +import java.util.Map; | ||
| 24 | 28 | ||
| 25 | /** | 29 | /** |
| 26 | * 云片短信实现类 | 30 | * 云片短信实现类 |
| @@ -29,7 +33,7 @@ import java.util.*; | @@ -29,7 +33,7 @@ import java.util.*; | ||
| 29 | * @date 9:48 2021/3/5 | 33 | * @date 9:48 2021/3/5 |
| 30 | */ | 34 | */ |
| 31 | @Slf4j | 35 | @Slf4j |
| 32 | -public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSmsClient { | 36 | +public class YunpianSmsClient extends AbstractSmsClient { |
| 33 | 37 | ||
| 34 | private final YunpianClient client; | 38 | private final YunpianClient client; |
| 35 | 39 | ||
| @@ -47,14 +51,14 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | @@ -47,14 +51,14 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | ||
| 47 | } | 51 | } |
| 48 | 52 | ||
| 49 | @Override | 53 | @Override |
| 50 | - public SmsResult doSend(String templateApiId, SmsBody smsBody, Collection<String> targets) { | 54 | + public SmsResult doSend(String templateApiId, SmsBody smsBody, String targetPhone) { |
| 51 | Map<String, String> paramMap = new HashMap<>(); | 55 | Map<String, String> paramMap = new HashMap<>(); |
| 52 | - paramMap.put("apikey", getProperty().getApiKey()); | ||
| 53 | - paramMap.put("mobile", String.join(SmsConstants.COMMA, targets)); | ||
| 54 | - paramMap.put("text", formatContent(smsBody)); | ||
| 55 | - paramMap.put("callback", getProperty().getCallbackUrl()); | 56 | + paramMap.put(YunpianConstant.APIKEY, getProperty().getApiKey()); |
| 57 | + paramMap.put(YunpianConstant.MOBILE, String.join(SmsConstants.COMMA, targetPhone)); | ||
| 58 | + paramMap.put(YunpianConstant.TEXT, formatContent(smsBody)); | ||
| 59 | + paramMap.put(Helper.CALLBACK, getProperty().getCallbackUrl()); | ||
| 56 | 60 | ||
| 57 | - Result<SmsBatchSend> sendResult = client.sms().batch_send(paramMap); | 61 | + Result<SmsSingleSend> sendResult = client.sms().single_send(paramMap); |
| 58 | boolean success = sendResult.getCode().equals(Code.OK); | 62 | boolean success = sendResult.getCode().equals(Code.OK); |
| 59 | 63 | ||
| 60 | if (!success) { | 64 | if (!success) { |
| @@ -64,7 +68,7 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | @@ -64,7 +68,7 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | ||
| 64 | .setSuccess(success) | 68 | .setSuccess(success) |
| 65 | .setMessage(sendResult.getDetail()) | 69 | .setMessage(sendResult.getDetail()) |
| 66 | .setCode(sendResult.getCode().toString()) | 70 | .setCode(sendResult.getCode().toString()) |
| 67 | - .setApiId(sendResult.getData().getData().get(0).getSid().toString()); | 71 | + .setApiId(sendResult.getData().getSid().toString()); |
| 68 | } | 72 | } |
| 69 | 73 | ||
| 70 | 74 | ||
| @@ -96,26 +100,16 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | @@ -96,26 +100,16 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | ||
| 96 | } | 100 | } |
| 97 | 101 | ||
| 98 | 102 | ||
| 103 | + /** | ||
| 104 | + * 云片的比较复杂,又是加密又是套娃的 | ||
| 105 | + */ | ||
| 99 | @Override | 106 | @Override |
| 100 | - public List<SmsResultDetail> getSmsSendResult(ServletRequest request) throws UnsupportedEncodingException { | ||
| 101 | - List<Map<String, String>> stringStringMap = getSendResult(request); | ||
| 102 | - List<SmsResultDetail> resultDetailList = new ArrayList<>(stringStringMap.size()); | ||
| 103 | - stringStringMap.forEach(map -> { | ||
| 104 | - SmsResultDetail detail = new SmsResultDetail(); | ||
| 105 | - | ||
| 106 | - detail.setPhone(map.get("mobile")); | ||
| 107 | - detail.setMessage(map.get("error_msg")); | ||
| 108 | - detail.setSendTime(DateUtil.parseTime(map.get("user_receive_time"))); | ||
| 109 | - String reportStatus = map.get("report_status"); | ||
| 110 | - detail.setSendStatus(reportStatus.equals(SmsConstants.SUCCESS) | ||
| 111 | - ? SmsSendStatusEnum.SEND_SUCCESS.getStatus() | ||
| 112 | - : SmsSendStatusEnum.SEND_FAIL.getStatus() | ||
| 113 | - ); | ||
| 114 | - resultDetailList.add(detail); | ||
| 115 | - }); | ||
| 116 | - return resultDetailList; | 107 | + public SmsResultDetail smsSendCallbackHandle(ServletRequest request) throws UnsupportedEncodingException { |
| 108 | + Map<String, String> map = getRequestParams(request); | ||
| 109 | + return Helper.getSmsResultDetailByParam(map); | ||
| 117 | } | 110 | } |
| 118 | 111 | ||
| 112 | + | ||
| 119 | /** | 113 | /** |
| 120 | * 从 request 中获取请求中传入的短信发送结果信息 | 114 | * 从 request 中获取请求中传入的短信发送结果信息 |
| 121 | * | 115 | * |
| @@ -123,10 +117,58 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | @@ -123,10 +117,58 @@ public class YunpianSmsClient extends AbstractSmsClient implements HadCallbackSm | ||
| 123 | * @return 短信发送结果信息 | 117 | * @return 短信发送结果信息 |
| 124 | * @throws UnsupportedEncodingException 解码异常 | 118 | * @throws UnsupportedEncodingException 解码异常 |
| 125 | */ | 119 | */ |
| 126 | - private List<Map<String, String>> getSendResult(ServletRequest request) throws UnsupportedEncodingException { | 120 | + private Map<String, String> getRequestParams(ServletRequest request) throws UnsupportedEncodingException { |
| 127 | Map<String, String[]> parameterMap = request.getParameterMap(); | 121 | Map<String, String[]> parameterMap = request.getParameterMap(); |
| 128 | String[] smsStatuses = parameterMap.get(YunpianConstant.SMS_STATUS); | 122 | String[] smsStatuses = parameterMap.get(YunpianConstant.SMS_STATUS); |
| 129 | String encode = URLEncoder.encode(smsStatuses[0], CharsetUtil.UTF_8); | 123 | String encode = URLEncoder.encode(smsStatuses[0], CharsetUtil.UTF_8); |
| 130 | - return JsonUtils.parseByType(encode, callbackType); | 124 | + List<Map<String, String>> paramList = JsonUtils.parseByType(encode, callbackType); |
| 125 | + if (CollectionUtil.isNotEmpty(paramList)) { | ||
| 126 | + return paramList.get(0); | ||
| 127 | + } | ||
| 128 | + throw new IllegalArgumentException("YunpianSmsClient getRequestParams fail! can't format RequestParam: " | ||
| 129 | + + JsonUtils.toJsonString(request.getParameterMap())); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * 云片的回调函数的一些辅助方法 | ||
| 134 | + */ | ||
| 135 | + private static class Helper { | ||
| 136 | + | ||
| 137 | + //短信唯一标识 | ||
| 138 | + private final static String API_ID = "sid"; | ||
| 139 | + | ||
| 140 | + //回调地址· | ||
| 141 | + private final static String CALLBACK = "callback"; | ||
| 142 | + | ||
| 143 | + //手机号 | ||
| 144 | + private final static String MOBILE = "mobile"; | ||
| 145 | + | ||
| 146 | + //错误信息 | ||
| 147 | + private final static String ERROR_MSG = "error_msg"; | ||
| 148 | + | ||
| 149 | + //用户接收时间 字符串 标准格式 | ||
| 150 | + private final static String USER_RECEIVE_TIME = "user_receive_time"; | ||
| 151 | + | ||
| 152 | + //发送状态 | ||
| 153 | + private final static String REPORT_STATUS = "report_status"; | ||
| 154 | + | ||
| 155 | + private static int getSendStatus(Map<String, String> map) { | ||
| 156 | + String reportStatus = map.get(REPORT_STATUS); | ||
| 157 | + return SmsConstants.SUCCESS.equals(reportStatus) | ||
| 158 | + ? SmsSendStatusEnum.SEND_SUCCESS.getStatus() | ||
| 159 | + : SmsSendStatusEnum.SEND_FAIL.getStatus(); | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + public static SmsResultDetail getSmsResultDetailByParam(Map<String, String> map) { | ||
| 163 | + SmsResultDetail detail = new SmsResultDetail(); | ||
| 164 | + detail.setPhone(map.get(MOBILE)); | ||
| 165 | + detail.setMessage(map.get(ERROR_MSG)); | ||
| 166 | + detail.setSendTime(DateUtil.parseTime(map.get(USER_RECEIVE_TIME))); | ||
| 167 | + detail.setSendStatus(getSendStatus(map)); | ||
| 168 | + detail.setApiId(API_ID); | ||
| 169 | + | ||
| 170 | + detail.setCallbackResponseBody(SmsConstants.SUCCESS); | ||
| 171 | + return detail; | ||
| 172 | + } | ||
| 131 | } | 173 | } |
| 132 | } | 174 | } |
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsClientFactory.java
| @@ -2,12 +2,15 @@ package cn.iocoder.dashboard.framework.sms.core; | @@ -2,12 +2,15 @@ package cn.iocoder.dashboard.framework.sms.core; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.common.exception.ServiceException; | 3 | import cn.iocoder.dashboard.common.exception.ServiceException; |
| 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 5 | -import cn.iocoder.dashboard.framework.sms.client.AliyunSmsClient; | 5 | +import cn.iocoder.dashboard.framework.sms.client.impl.ali.AliyunSmsClient; |
| 6 | +import cn.iocoder.dashboard.framework.sms.client.impl.yunpian.YunpianSmsClient; | ||
| 6 | import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; | 7 | import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; |
| 7 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; | 8 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; |
| 8 | import cn.iocoder.dashboard.framework.sms.core.property.SmsTemplateProperty; | 9 | import cn.iocoder.dashboard.framework.sms.core.property.SmsTemplateProperty; |
| 10 | +import cn.iocoder.dashboard.util.json.JsonUtils; | ||
| 9 | import org.springframework.stereotype.Component; | 11 | import org.springframework.stereotype.Component; |
| 10 | 12 | ||
| 13 | +import javax.servlet.ServletRequest; | ||
| 11 | import java.util.Collection; | 14 | import java.util.Collection; |
| 12 | import java.util.Map; | 15 | import java.util.Map; |
| 13 | import java.util.concurrent.ConcurrentHashMap; | 16 | import java.util.concurrent.ConcurrentHashMap; |
| @@ -54,6 +57,8 @@ public class SmsClientFactory { | @@ -54,6 +57,8 @@ public class SmsClientFactory { | ||
| 54 | switch (channelEnum) { | 57 | switch (channelEnum) { |
| 55 | case ALI: | 58 | case ALI: |
| 56 | return new AliyunSmsClient(channelVO); | 59 | return new AliyunSmsClient(channelVO); |
| 60 | + case YUN_PIAN: | ||
| 61 | + return new YunpianSmsClient(channelVO); | ||
| 57 | // TODO fill more channel | 62 | // TODO fill more channel |
| 58 | default: | 63 | default: |
| 59 | break; | 64 | break; |
| @@ -102,4 +107,28 @@ public class SmsClientFactory { | @@ -102,4 +107,28 @@ public class SmsClientFactory { | ||
| 102 | return smsTemplateProperty.getApiTemplateId(); | 107 | return smsTemplateProperty.getApiTemplateId(); |
| 103 | } | 108 | } |
| 104 | 109 | ||
| 110 | + | ||
| 111 | + /** | ||
| 112 | + * 从短信发送回调函数请求中获取用于唯一确定一条send_lod的apiId | ||
| 113 | + * | ||
| 114 | + * @param callbackRequest 短信发送回调函数请求 | ||
| 115 | + * @return 第三方平台短信唯一标识 | ||
| 116 | + */ | ||
| 117 | + public SmsResultDetail getSmsResultDetailFromCallbackQuery(ServletRequest callbackRequest) { | ||
| 118 | + | ||
| 119 | + for (Long channelId : smsSenderMap.keySet()) { | ||
| 120 | + AbstractSmsClient smsClient = smsSenderMap.get(channelId); | ||
| 121 | + try { | ||
| 122 | + SmsResultDetail smsSendResult = smsClient.smsSendCallbackHandle(callbackRequest); | ||
| 123 | + if (smsSendResult != null) { | ||
| 124 | + return smsSendResult; | ||
| 125 | + } | ||
| 126 | + } catch (Exception ignored) { | ||
| 127 | + } | ||
| 128 | + } | ||
| 129 | + throw new IllegalArgumentException("getSmsResultDetailFromCallbackQuery fail! don't match SmsClient by RequestParam: " | ||
| 130 | + + JsonUtils.toJsonString(callbackRequest.getParameterMap())); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + | ||
| 105 | } | 134 | } |
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResult.java
| @@ -32,11 +32,6 @@ public class SmsResult implements Serializable { | @@ -32,11 +32,6 @@ public class SmsResult implements Serializable { | ||
| 32 | */ | 32 | */ |
| 33 | private String message; | 33 | private String message; |
| 34 | 34 | ||
| 35 | - /** | ||
| 36 | - * 用于查询发送结果的参数 | ||
| 37 | - */ | ||
| 38 | - private String sendResultParam; | ||
| 39 | - | ||
| 40 | public static SmsResult failResult(String message) { | 35 | public static SmsResult failResult(String message) { |
| 41 | SmsResult resultBody = new SmsResult(); | 36 | SmsResult resultBody = new SmsResult(); |
| 42 | resultBody.setSuccess(false); | 37 | resultBody.setSuccess(false); |
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java
| @@ -12,6 +12,11 @@ import java.util.Date; | @@ -12,6 +12,11 @@ import java.util.Date; | ||
| 12 | public class SmsResultDetail implements Serializable { | 12 | public class SmsResultDetail implements Serializable { |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | + * 唯一标识 | ||
| 16 | + */ | ||
| 17 | + private String apiId; | ||
| 18 | + | ||
| 19 | + /** | ||
| 15 | * 短信发送状态 {@link cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum} | 20 | * 短信发送状态 {@link cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum} |
| 16 | */ | 21 | */ |
| 17 | private Integer sendStatus; | 22 | private Integer sendStatus; |
| @@ -30,4 +35,9 @@ public class SmsResultDetail implements Serializable { | @@ -30,4 +35,9 @@ public class SmsResultDetail implements Serializable { | ||
| 30 | * 时间 | 35 | * 时间 |
| 31 | */ | 36 | */ |
| 32 | private Date sendTime; | 37 | private Date sendTime; |
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 接口返回值 | ||
| 41 | + */ | ||
| 42 | + private Object callbackResponseBody; | ||
| 33 | } | 43 | } |
src/main/java/cn/iocoder/dashboard/framework/sms/core/enums/SmsChannelEnum.java
| @@ -14,8 +14,8 @@ import lombok.Getter; | @@ -14,8 +14,8 @@ import lombok.Getter; | ||
| 14 | public enum SmsChannelEnum { | 14 | public enum SmsChannelEnum { |
| 15 | 15 | ||
| 16 | ALI("ALI", "阿里"), | 16 | ALI("ALI", "阿里"), |
| 17 | + YUN_PIAN("YUN_PIAN", "云片"), | ||
| 17 | HUA_WEI("HUA_WEI", "华为"), | 18 | HUA_WEI("HUA_WEI", "华为"), |
| 18 | - QI_NIU("QI_NIU", "七牛"), | ||
| 19 | TENCENT("TENCENT", "腾讯"); | 19 | TENCENT("TENCENT", "腾讯"); |
| 20 | 20 | ||
| 21 | private final String code; | 21 | private final String code; |
src/main/java/cn/iocoder/dashboard/modules/infra/controller/redis/RedisController.java
| 1 | -package cn.iocoder.dashboard.modules.infra.controller.redis; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.util.StrUtil; | ||
| 4 | -import cn.iocoder.dashboard.common.pojo.CommonResult; | ||
| 5 | -import cn.iocoder.dashboard.framework.redis.core.RedisKeyRegistry; | ||
| 6 | -import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisKeyRespVO; | ||
| 7 | -import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisMonitorRespVO; | ||
| 8 | -import org.springframework.data.redis.connection.RedisServerCommands; | ||
| 9 | -import org.springframework.data.redis.core.RedisCallback; | ||
| 10 | -import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 11 | -import org.springframework.web.bind.annotation.GetMapping; | ||
| 12 | -import org.springframework.web.bind.annotation.RequestMapping; | ||
| 13 | -import org.springframework.web.bind.annotation.RestController; | ||
| 14 | - | ||
| 15 | -import javax.annotation.Resource; | ||
| 16 | -import java.util.ArrayList; | ||
| 17 | -import java.util.List; | ||
| 18 | -import java.util.Properties; | ||
| 19 | -import java.util.stream.Collectors; | ||
| 20 | - | ||
| 21 | -import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||
| 22 | - | ||
| 23 | -@RestController | ||
| 24 | -@RequestMapping("/infra/redis") | ||
| 25 | -public class RedisController { | ||
| 26 | - | ||
| 27 | - @Resource | ||
| 28 | - private StringRedisTemplate stringRedisTemplate; | ||
| 29 | - | ||
| 30 | -// @PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')") | ||
| 31 | - @GetMapping("/get-monitor-info") | ||
| 32 | - public CommonResult<InfRedisMonitorRespVO> getRedisMonitorInfo() { | ||
| 33 | - // 获得 Redis 统计信息 | ||
| 34 | - Properties info = stringRedisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info); | ||
| 35 | - Long dbSize = stringRedisTemplate.execute(RedisServerCommands::dbSize); | ||
| 36 | - Properties commandStats = stringRedisTemplate.execute(( | ||
| 37 | - RedisCallback<Properties>) connection -> connection.info("commandstats")); | ||
| 38 | - assert commandStats != null; // 断言,避免警告 | ||
| 39 | - | ||
| 40 | - // 拼接结果返回 | ||
| 41 | - InfRedisMonitorRespVO respVO = InfRedisMonitorRespVO.builder().info(info).dbSize(dbSize) | ||
| 42 | - .commandStats(new ArrayList<>(commandStats.size())).build(); | ||
| 43 | - commandStats.forEach((key, value) -> { | ||
| 44 | - respVO.getCommandStats().add(InfRedisMonitorRespVO.CommandStat.builder() | ||
| 45 | - .command(StrUtil.subAfter((String) key, "cmdstat_", false)) | ||
| 46 | - .calls(Integer.valueOf(StrUtil.subBetween((String) value, "calls=", ","))) | ||
| 47 | - .usec(Integer.valueOf(StrUtil.subBetween((String) value, "usec=", ","))) | ||
| 48 | - .build()); | ||
| 49 | - }); | ||
| 50 | - return success(respVO); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | -// @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 54 | - @GetMapping("/get-key-list") | ||
| 55 | - public CommonResult<List<InfRedisKeyRespVO>> getKeyList() { | ||
| 56 | - List<InfRedisKeyRespVO> respVOList = RedisKeyRegistry.list().stream() | ||
| 57 | - .map(define -> InfRedisKeyRespVO.builder() | ||
| 58 | - .keyTemplate(define.getKeyTemplate()) | ||
| 59 | - .keyType(define.getKeyType().name()) | ||
| 60 | - .valueType(define.getValueType().getName()) | ||
| 61 | - .timeoutType(define.getTimeoutType().getType()) | ||
| 62 | - .timeout((int) define.getTimeout().getSeconds()) | ||
| 63 | - .build()) | ||
| 64 | - .collect(Collectors.toList()); | ||
| 65 | - return success(respVOList); | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | -} | 1 | +//package cn.iocoder.dashboard.modules.infra.controller.redis; |
| 2 | +// | ||
| 3 | +//import cn.hutool.core.util.StrUtil; | ||
| 4 | +//import cn.iocoder.dashboard.common.pojo.CommonResult; | ||
| 5 | +//import cn.iocoder.dashboard.framework.redis.core.RedisKeyRegistry; | ||
| 6 | +//import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisKeyRespVO; | ||
| 7 | +//import cn.iocoder.dashboard.modules.infra.controller.redis.vo.InfRedisMonitorRespVO; | ||
| 8 | +//import org.springframework.data.redis.connection.RedisServerCommands; | ||
| 9 | +//import org.springframework.data.redis.core.RedisCallback; | ||
| 10 | +//import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 11 | +//import org.springframework.web.bind.annotation.GetMapping; | ||
| 12 | +//import org.springframework.web.bind.annotation.RequestMapping; | ||
| 13 | +//import org.springframework.web.bind.annotation.RestController; | ||
| 14 | +// | ||
| 15 | +//import javax.annotation.Resource; | ||
| 16 | +//import java.util.ArrayList; | ||
| 17 | +//import java.util.List; | ||
| 18 | +//import java.util.Properties; | ||
| 19 | +//import java.util.stream.Collectors; | ||
| 20 | +// | ||
| 21 | +//import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||
| 22 | +// | ||
| 23 | +//@RestController | ||
| 24 | +//@RequestMapping("/infra/redis") | ||
| 25 | +//public class RedisController { | ||
| 26 | +// | ||
| 27 | +// @Resource | ||
| 28 | +// private StringRedisTemplate stringRedisTemplate; | ||
| 29 | +// | ||
| 30 | +//// @PreAuthorize("@ss.hasPermission('infra:redis:get-monitor-info')") | ||
| 31 | +// @GetMapping("/get-monitor-info") | ||
| 32 | +// public CommonResult<InfRedisMonitorRespVO> getRedisMonitorInfo() { | ||
| 33 | +// // 获得 Redis 统计信息 | ||
| 34 | +// Properties info = stringRedisTemplate.execute((RedisCallback<Properties>) RedisServerCommands::info); | ||
| 35 | +// Long dbSize = stringRedisTemplate.execute(RedisServerCommands::dbSize); | ||
| 36 | +// Properties commandStats = stringRedisTemplate.execute(( | ||
| 37 | +// RedisCallback<Properties>) connection -> connection.info("commandstats")); | ||
| 38 | +// assert commandStats != null; // 断言,避免警告 | ||
| 39 | +// | ||
| 40 | +// // 拼接结果返回 | ||
| 41 | +// InfRedisMonitorRespVO respVO = InfRedisMonitorRespVO.builder().info(info).dbSize(dbSize) | ||
| 42 | +// .commandStats(new ArrayList<>(commandStats.size())).build(); | ||
| 43 | +// commandStats.forEach((key, value) -> { | ||
| 44 | +// respVO.getCommandStats().add(InfRedisMonitorRespVO.CommandStat.builder() | ||
| 45 | +// .command(StrUtil.subAfter((String) key, "cmdstat_", false)) | ||
| 46 | +// .calls(Integer.valueOf(StrUtil.subBetween((String) value, "calls=", ","))) | ||
| 47 | +// .usec(Integer.valueOf(StrUtil.subBetween((String) value, "usec=", ","))) | ||
| 48 | +// .build()); | ||
| 49 | +// }); | ||
| 50 | +// return success(respVO); | ||
| 51 | +// } | ||
| 52 | +// | ||
| 53 | +//// @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 54 | +// @GetMapping("/get-key-list") | ||
| 55 | +// public CommonResult<List<InfRedisKeyRespVO>> getKeyList() { | ||
| 56 | +// List<InfRedisKeyRespVO> respVOList = RedisKeyRegistry.list().stream() | ||
| 57 | +// .map(define -> InfRedisKeyRespVO.builder() | ||
| 58 | +// .keyTemplate(define.getKeyTemplate()) | ||
| 59 | +// .keyType(define.getKeyType().name()) | ||
| 60 | +// .valueType(define.getValueType().getName()) | ||
| 61 | +// .timeoutType(define.getTimeoutType().getType()) | ||
| 62 | +// .timeout((int) define.getTimeout().getSeconds()) | ||
| 63 | +// .build()) | ||
| 64 | +// .collect(Collectors.toList()); | ||
| 65 | +// return success(respVOList); | ||
| 66 | +// } | ||
| 67 | +// | ||
| 68 | +//} |
src/main/java/cn/iocoder/dashboard/modules/system/controller/sms/SmsDefaultCallbackController.java
| 1 | package cn.iocoder.dashboard.modules.system.controller.sms; | 1 | package cn.iocoder.dashboard.modules.system.controller.sms; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 4 | +import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendStreamProducer; | ||
| 3 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; | 5 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; |
| 6 | +import io.swagger.annotations.Api; | ||
| 7 | +import io.swagger.annotations.ApiOperation; | ||
| 8 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 9 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 4 | import org.springframework.web.bind.annotation.RequestMapping; | 10 | import org.springframework.web.bind.annotation.RequestMapping; |
| 5 | import org.springframework.web.bind.annotation.RestController; | 11 | import org.springframework.web.bind.annotation.RestController; |
| 6 | 12 | ||
| 7 | import javax.annotation.Resource; | 13 | import javax.annotation.Resource; |
| 8 | import javax.servlet.ServletRequest; | 14 | import javax.servlet.ServletRequest; |
| 15 | +import java.util.Arrays; | ||
| 16 | +import java.util.Map; | ||
| 9 | 17 | ||
| 10 | /** | 18 | /** |
| 11 | * 短信默认回调接口 | 19 | * 短信默认回调接口 |
| @@ -13,15 +21,33 @@ import javax.servlet.ServletRequest; | @@ -13,15 +21,33 @@ import javax.servlet.ServletRequest; | ||
| 13 | * @author zzf | 21 | * @author zzf |
| 14 | * @date 2021/3/5 8:59 | 22 | * @date 2021/3/5 8:59 |
| 15 | */ | 23 | */ |
| 16 | -@RestController("/sms/callback") | 24 | +@Api(tags = "短信回调api") |
| 25 | +@RestController | ||
| 26 | +@RequestMapping("/sms/callback") | ||
| 17 | public class SmsDefaultCallbackController { | 27 | public class SmsDefaultCallbackController { |
| 18 | 28 | ||
| 19 | @Resource | 29 | @Resource |
| 20 | private SysSmsService smsService; | 30 | private SysSmsService smsService; |
| 21 | 31 | ||
| 22 | - @RequestMapping("/sms-send") | ||
| 23 | - public Object sendSmsCallback(ServletRequest request){ | 32 | + |
| 33 | + @ApiOperation(value = "短信发送回调接口") | ||
| 34 | + @PostMapping("/sms-send") | ||
| 35 | + public Object sendSmsCallback(ServletRequest request) { | ||
| 24 | return smsService.smsSendCallbackHandle(request); | 36 | return smsService.smsSendCallbackHandle(request); |
| 25 | } | 37 | } |
| 26 | 38 | ||
| 39 | +/* | ||
| 40 | + @Resource | ||
| 41 | + private SmsSendStreamProducer smsSendStreamProducer; | ||
| 42 | + | ||
| 43 | + @ApiOperation("redis stream测试") | ||
| 44 | + @GetMapping("/test/redis/stream") | ||
| 45 | + public void test() { | ||
| 46 | + SmsBody smsBody = new SmsBody(); | ||
| 47 | + smsBody.setSmsLogId(1L); | ||
| 48 | + smsBody.setTemplateCode("sdf"); | ||
| 49 | + smsBody.setTemplateContent("sdf"); | ||
| 50 | + smsSendStreamProducer.sendSmsSendMessage(smsBody, "18216466755"); | ||
| 51 | + }*/ | ||
| 52 | + | ||
| 27 | } | 53 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dao/sms/SysSmsQueryLogMapper.java
| @@ -14,14 +14,21 @@ public interface SysSmsQueryLogMapper extends BaseMapper<SysSmsQueryLogDO> { | @@ -14,14 +14,21 @@ public interface SysSmsQueryLogMapper extends BaseMapper<SysSmsQueryLogDO> { | ||
| 14 | 14 | ||
| 15 | /** | 15 | /** |
| 16 | * 查询还没有获取发送结果的短信请求信息 | 16 | * 查询还没有获取发送结果的短信请求信息 |
| 17 | - * | ||
| 18 | - * @return | ||
| 19 | */ | 17 | */ |
| 20 | default List<SysSmsQueryLogDO> selectNoResultQueryLogList() { | 18 | default List<SysSmsQueryLogDO> selectNoResultQueryLogList() { |
| 21 | return this.selectList(new LambdaQueryWrapper<SysSmsQueryLogDO>() | 19 | return this.selectList(new LambdaQueryWrapper<SysSmsQueryLogDO>() |
| 22 | .eq(SysSmsQueryLogDO::getSendStatus, SmsSendStatusEnum.QUERY_SUCCESS) | 20 | .eq(SysSmsQueryLogDO::getSendStatus, SmsSendStatusEnum.QUERY_SUCCESS) |
| 23 | .eq(SysSmsQueryLogDO::getGotResult, DefaultBitFieldEnum.NO) | 21 | .eq(SysSmsQueryLogDO::getGotResult, DefaultBitFieldEnum.NO) |
| 24 | - .eq(SysSmsQueryLogDO::getHadCallback, DefaultBitFieldEnum.NO) | ||
| 25 | ); | 22 | ); |
| 26 | } | 23 | } |
| 24 | + | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 根据APIId修改对象 | ||
| 28 | + */ | ||
| 29 | + default boolean updateByApiId(SysSmsQueryLogDO queryLogDO, String apiId) { | ||
| 30 | + return update(queryLogDO, new LambdaQueryWrapper<SysSmsQueryLogDO>() | ||
| 31 | + .eq(SysSmsQueryLogDO::getApiId, apiId) | ||
| 32 | + ) > 0; | ||
| 33 | + } | ||
| 27 | } | 34 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsChannelDO.java
| @@ -28,11 +28,6 @@ public class SysSmsChannelDO extends BaseDO { | @@ -28,11 +28,6 @@ public class SysSmsChannelDO extends BaseDO { | ||
| 28 | private String code; | 28 | private String code; |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | - * 是否拥有回答(0否 1是) | ||
| 32 | - */ | ||
| 33 | - private Integer had_callback; | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | * 短信发送回调url | 31 | * 短信发送回调url |
| 37 | */ | 32 | */ |
| 38 | private String callback_url; | 33 | private String callback_url; |
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/dataobject/sms/SysSmsQueryLogDO.java
| 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms; | 1 | package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms; |
| 2 | 2 | ||
| 3 | -import com.baomidou.mybatisplus.annotation.TableField; | ||
| 4 | import com.baomidou.mybatisplus.annotation.TableName; | 3 | import com.baomidou.mybatisplus.annotation.TableName; |
| 5 | -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; | ||
| 6 | import lombok.Data; | 4 | import lombok.Data; |
| 7 | import lombok.EqualsAndHashCode; | 5 | import lombok.EqualsAndHashCode; |
| 8 | import lombok.experimental.Accessors; | 6 | import lombok.experimental.Accessors; |
| 9 | 7 | ||
| 10 | import java.io.Serializable; | 8 | import java.io.Serializable; |
| 11 | import java.util.Date; | 9 | import java.util.Date; |
| 12 | -import java.util.List; | ||
| 13 | 10 | ||
| 14 | /** | 11 | /** |
| 15 | * 短信日志 | 12 | * 短信日志 |
| @@ -29,6 +26,11 @@ public class SysSmsQueryLogDO implements Serializable { | @@ -29,6 +26,11 @@ public class SysSmsQueryLogDO implements Serializable { | ||
| 29 | private Long id; | 26 | private Long id; |
| 30 | 27 | ||
| 31 | /** | 28 | /** |
| 29 | + * 第三方唯一标识 | ||
| 30 | + */ | ||
| 31 | + private String apiId; | ||
| 32 | + | ||
| 33 | + /** | ||
| 32 | * 短信渠道编码(来自枚举类) | 34 | * 短信渠道编码(来自枚举类) |
| 33 | */ | 35 | */ |
| 34 | private String channelCode; | 36 | private String channelCode; |
| @@ -46,8 +48,7 @@ public class SysSmsQueryLogDO implements Serializable { | @@ -46,8 +48,7 @@ public class SysSmsQueryLogDO implements Serializable { | ||
| 46 | /** | 48 | /** |
| 47 | * 手机号 | 49 | * 手机号 |
| 48 | */ | 50 | */ |
| 49 | - @TableField(typeHandler = JacksonTypeHandler.class) | ||
| 50 | - private List<String> phones; | 51 | + private String phone; |
| 51 | 52 | ||
| 52 | /** | 53 | /** |
| 53 | * 内容 | 54 | * 内容 |
| @@ -67,16 +68,6 @@ public class SysSmsQueryLogDO implements Serializable { | @@ -67,16 +68,6 @@ public class SysSmsQueryLogDO implements Serializable { | ||
| 67 | private Integer gotResult; | 68 | private Integer gotResult; |
| 68 | 69 | ||
| 69 | /** | 70 | /** |
| 70 | - * 是否拥有回调函数(0否 1是) | ||
| 71 | - */ | ||
| 72 | - private Integer hadCallback; | ||
| 73 | - | ||
| 74 | - /** | ||
| 75 | - * 结果(对象json字符串) | ||
| 76 | - */ | ||
| 77 | - private String sendResultParam; | ||
| 78 | - | ||
| 79 | - /** | ||
| 80 | * 备注 | 71 | * 备注 |
| 81 | */ | 72 | */ |
| 82 | private String remark; | 73 | private String remark; |
| @@ -91,4 +82,9 @@ public class SysSmsQueryLogDO implements Serializable { | @@ -91,4 +82,9 @@ public class SysSmsQueryLogDO implements Serializable { | ||
| 91 | */ | 82 | */ |
| 92 | private Date createTime; | 83 | private Date createTime; |
| 93 | 84 | ||
| 85 | + /** | ||
| 86 | + * 发送时间 | ||
| 87 | + */ | ||
| 88 | + private Date sendTime; | ||
| 89 | + | ||
| 94 | } | 90 | } |
src/main/java/cn/iocoder/dashboard/modules/system/dal/redis/RedisKeyConstants.java
| @@ -28,6 +28,6 @@ public interface RedisKeyConstants { | @@ -28,6 +28,6 @@ public interface RedisKeyConstants { | ||
| 28 | * key 的 format 的参数是 uuid | 28 | * key 的 format 的参数是 uuid |
| 29 | */ | 29 | */ |
| 30 | RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("captcha_code:%s", STRING, String.class, | 30 | RedisKeyDefine CAPTCHA_CODE = new RedisKeyDefine("captcha_code:%s", STRING, String.class, |
| 31 | - RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); | 31 | + Duration.ofMinutes(30)); |
| 32 | 32 | ||
| 33 | } | 33 | } |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/dept/SysDeptRefreshConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/dept/SysDeptRefreshConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.dept; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.consumer.dept; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.dept.SysDeptRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.dept.SysDeptRefreshMessage; |
| 5 | import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; | 5 | import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/dict/SysDictDataRefreshConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/dict/SysDictDataRefreshConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.dict; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.consumer.dict; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.dict.SysDictDataRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.dict.SysDictDataRefreshMessage; |
| 5 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; | 5 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/permission/SysMenuRefreshConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/permission/SysMenuRefreshConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.consumer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysMenuRefreshMessage; |
| 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; | 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/permission/SysRoleMenuRefreshConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/permission/SysRoleMenuRefreshConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.consumer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysRoleMenuRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysRoleMenuRefreshMessage; |
| 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/permission/SysRoleRefreshConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/permission/SysRoleRefreshConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.consumer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysRoleRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysRoleRefreshMessage; |
| 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; | 5 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; |
| 6 | import lombok.extern.slf4j.Slf4j; | 6 | import lombok.extern.slf4j.Slf4j; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/consumer/sms/SmsSendConsumer.java
0 → 100644
| 1 | +//package cn.iocoder.dashboard.modules.system.redis.mq.consumer.sms; | ||
| 2 | +// | ||
| 3 | +//import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | ||
| 4 | +//import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | ||
| 5 | +//import cn.iocoder.dashboard.framework.sms.core.SmsResult; | ||
| 6 | +//import cn.iocoder.dashboard.modules.system.redis.mq.message.dept.SysDeptRefreshMessage; | ||
| 7 | +//import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendMessage; | ||
| 8 | +//import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; | ||
| 9 | +//import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; | ||
| 10 | +//import lombok.extern.slf4j.Slf4j; | ||
| 11 | +//import org.springframework.beans.factory.annotation.Autowired; | ||
| 12 | +//import org.springframework.data.redis.connection.stream.Consumer; | ||
| 13 | +//import org.springframework.data.redis.connection.stream.ObjectRecord; | ||
| 14 | +//import org.springframework.data.redis.connection.stream.ReadOffset; | ||
| 15 | +//import org.springframework.data.redis.connection.stream.StreamOffset; | ||
| 16 | +//import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 17 | +//import org.springframework.stereotype.Component; | ||
| 18 | +// | ||
| 19 | +//import javax.annotation.Resource; | ||
| 20 | +// | ||
| 21 | +///** | ||
| 22 | +// * 针对 {@link SysDeptRefreshMessage} 的消费者 | ||
| 23 | +// * | ||
| 24 | +// * @author 芋道源码 | ||
| 25 | +// */ | ||
| 26 | +//@Component | ||
| 27 | +//@Slf4j | ||
| 28 | +//public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessage> { | ||
| 29 | +// | ||
| 30 | +// @Resource | ||
| 31 | +// private SysSmsChannelService smsChannelService; | ||
| 32 | +// | ||
| 33 | +// @Resource | ||
| 34 | +// private SysSmsQueryLogService smsQueryLogService; | ||
| 35 | +// | ||
| 36 | +// @Autowired | ||
| 37 | +// StringRedisTemplate redisTemplate; | ||
| 38 | +// | ||
| 39 | +// @Override | ||
| 40 | +// public void onMessage(SmsSendMessage message) { | ||
| 41 | +// | ||
| 42 | +// redisTemplate.opsForStream().add(ObjectRecord.create("String", message)); | ||
| 43 | +// | ||
| 44 | +// redisTemplate.opsForStream().read(Consumer.from("",""), StreamOffset.create("", ReadOffset.lastConsumed())); | ||
| 45 | +// | ||
| 46 | +// | ||
| 47 | +// | ||
| 48 | +// log.info("[onMessage][收到 发送短信 消息], content: " + message.toString()); | ||
| 49 | +// AbstractSmsClient smsClient = smsChannelService.getSmsClient(message.getSmsBody().getTemplateCode()); | ||
| 50 | +// String templateApiId = smsChannelService.getSmsTemplateApiIdByCode(message.getSmsBody().getTemplateCode()); | ||
| 51 | +// | ||
| 52 | +// SmsResult result = smsClient.send(templateApiId, message.getSmsBody(), message.getTargetPhone()); | ||
| 53 | +// smsQueryLogService.afterSendLog(message.getSmsBody().getSmsLogId(), result); | ||
| 54 | +// } | ||
| 55 | +// | ||
| 56 | +//} |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/dept/SysDeptRefreshMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/message/dept/SysDeptRefreshMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.dept; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.message.dept; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/dict/SysDictDataRefreshMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/message/dict/SysDictDataRefreshMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.dict; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.message.dict; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/permission/SysMenuRefreshMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/message/permission/SysMenuRefreshMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.message.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/permission/SysRoleMenuRefreshMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/message/permission/SysRoleMenuRefreshMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.message.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/permission/SysRoleRefreshMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/message/permission/SysRoleRefreshMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.message.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | 3 | import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dept/SysDeptProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/dept/SysDeptProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.dept; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.producer.dept; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.dept.SysDeptRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.dept.SysDeptRefreshMessage; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/dict/SysDictDataProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/dict/SysDictDataProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.dict; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.producer.dict; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.dict.SysDictDataRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.dict.SysDictDataRefreshMessage; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/permission/SysMenuProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/permission/SysMenuProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.producer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysMenuRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysMenuRefreshMessage; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/permission/SysPermissionProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/permission/SysPermissionProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.producer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysRoleMenuRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysRoleMenuRefreshMessage; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/permission/SysRoleProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/permission/SysRoleProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.permission; | 1 | +package cn.iocoder.dashboard.modules.system.redis.mq.producer.permission; |
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; |
| 4 | -import cn.iocoder.dashboard.modules.system.mq.message.permission.SysRoleRefreshMessage; | 4 | +import cn.iocoder.dashboard.modules.system.redis.mq.message.permission.SysRoleRefreshMessage; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 5 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | import org.springframework.stereotype.Component; | 6 | import org.springframework.stereotype.Component; |
| 7 | 7 |
src/main/java/cn/iocoder/dashboard/modules/system/redis/mq/producer/sms/SmsProducer.java
0 → 100644
| 1 | +//package cn.iocoder.dashboard.modules.system.redis.mq.producer.sms; | ||
| 2 | +// | ||
| 3 | +//import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | ||
| 4 | +//import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 5 | +//import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendMessage; | ||
| 6 | +//import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 7 | +//import org.springframework.stereotype.Component; | ||
| 8 | +// | ||
| 9 | +//import javax.annotation.Resource; | ||
| 10 | +// | ||
| 11 | +///** | ||
| 12 | +// * 短信的 Producer | ||
| 13 | +// */ | ||
| 14 | +//@Component | ||
| 15 | +//public class SmsProducer { | ||
| 16 | +// | ||
| 17 | +// @Resource | ||
| 18 | +// private StringRedisTemplate stringRedisTemplate; | ||
| 19 | +// | ||
| 20 | +// /** | ||
| 21 | +// * 发送 {@link SmsSendMessage} 消息 | ||
| 22 | +// */ | ||
| 23 | +// public void sendSmsSendMessage(SmsBody smsBody, String targetPhone) { | ||
| 24 | +// SmsSendMessage message = new SmsSendMessage(); | ||
| 25 | +// message.setSmsBody(smsBody); | ||
| 26 | +// message.setTargetPhone(targetPhone); | ||
| 27 | +// // TODO FROM 芋艿 TO ZZF:这块等未来改哈。这个方法目前是广播消费,会导致每个节点都发送一次。等后续封装出 redis stream 消息 | ||
| 28 | +// RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); | ||
| 29 | +// } | ||
| 30 | +// | ||
| 31 | +//} |
src/main/java/cn/iocoder/dashboard/modules/system/redis/stream/StreamConsumerRunner.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.system.redis.stream; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.dashboard.framework.redis.core.util.RedisStreamUtils; | ||
| 4 | +import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendMessage; | ||
| 5 | +import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendStreamConsumer; | ||
| 6 | +import lombok.extern.slf4j.Slf4j; | ||
| 7 | +import org.springframework.beans.factory.DisposableBean; | ||
| 8 | +import org.springframework.boot.ApplicationArguments; | ||
| 9 | +import org.springframework.boot.ApplicationRunner; | ||
| 10 | +import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
| 11 | +import org.springframework.data.redis.connection.stream.*; | ||
| 12 | +import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 13 | +import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
| 14 | +import org.springframework.data.redis.stream.StreamMessageListenerContainer; | ||
| 15 | +import org.springframework.data.redis.stream.StreamMessageListenerContainer.StreamMessageListenerContainerOptions; | ||
| 16 | +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
| 17 | +import org.springframework.stereotype.Component; | ||
| 18 | +import org.springframework.util.ErrorHandler; | ||
| 19 | + | ||
| 20 | +import javax.annotation.Resource; | ||
| 21 | +import java.net.InetAddress; | ||
| 22 | +import java.net.UnknownHostException; | ||
| 23 | +import java.time.Duration; | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +@Slf4j | ||
| 27 | +@Component | ||
| 28 | +public class StreamConsumerRunner implements ApplicationRunner, DisposableBean { | ||
| 29 | + | ||
| 30 | + @Resource | ||
| 31 | + RedisConnectionFactory redisConnectionFactory; | ||
| 32 | + | ||
| 33 | + @Resource | ||
| 34 | + ThreadPoolTaskExecutor threadPoolTaskExecutor; | ||
| 35 | + | ||
| 36 | + @Resource | ||
| 37 | + SmsSendStreamConsumer streamMessageListener; | ||
| 38 | + | ||
| 39 | + @Resource | ||
| 40 | + StringRedisTemplate stringRedisTemplate; | ||
| 41 | + | ||
| 42 | + private StreamMessageListenerContainer<String, ObjectRecord<String, SmsSendMessage>> streamMessageListenerContainer; | ||
| 43 | + | ||
| 44 | + @Override | ||
| 45 | + public void run(ApplicationArguments args) throws UnknownHostException { | ||
| 46 | + | ||
| 47 | + StreamInfo.XInfoGroups groups = stringRedisTemplate.opsForStream().groups(RedisStreamUtils.KEY_SMS_SEND); | ||
| 48 | + if (groups.isEmpty()) { | ||
| 49 | + stringRedisTemplate.opsForStream().createGroup(RedisStreamUtils.KEY_SMS_SEND, RedisStreamUtils.GROUP_SMS_SEND); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + | ||
| 53 | + // 创建配置对象 | ||
| 54 | + StreamMessageListenerContainerOptions<String, ObjectRecord<String, SmsSendMessage>> streamMessageListenerContainerOptions = StreamMessageListenerContainerOptions | ||
| 55 | + .builder() | ||
| 56 | + // 一次性最多拉取多少条消息 | ||
| 57 | + .batchSize(10) | ||
| 58 | + // 执行消息轮询的执行器 | ||
| 59 | + .executor(this.threadPoolTaskExecutor) | ||
| 60 | + // 消息消费异常的handler | ||
| 61 | + .errorHandler(new ErrorHandler() { | ||
| 62 | + @Override | ||
| 63 | + public void handleError(Throwable t) { | ||
| 64 | + // throw new RuntimeException(t); | ||
| 65 | + t.printStackTrace(); | ||
| 66 | + } | ||
| 67 | + }) | ||
| 68 | + // 超时时间,设置为0,表示不超时(超时后会抛出异常) | ||
| 69 | + .pollTimeout(Duration.ZERO) | ||
| 70 | + // 序列化器 | ||
| 71 | + .serializer(new StringRedisSerializer()) | ||
| 72 | + .targetType(SmsSendMessage.class) | ||
| 73 | + .build(); | ||
| 74 | + | ||
| 75 | + // 根据配置对象创建监听容器对象 | ||
| 76 | + StreamMessageListenerContainer<String, ObjectRecord<String, SmsSendMessage>> streamMessageListenerContainer = StreamMessageListenerContainer | ||
| 77 | + .create(this.redisConnectionFactory, streamMessageListenerContainerOptions); | ||
| 78 | + | ||
| 79 | + // 使用监听容器对象开始监听消费(使用的是手动确认方式) | ||
| 80 | + streamMessageListenerContainer.receive(Consumer.from(RedisStreamUtils.GROUP_SMS_SEND, InetAddress.getLocalHost().getHostName()), | ||
| 81 | + StreamOffset.create(RedisStreamUtils.KEY_SMS_SEND, ReadOffset.lastConsumed()), this.streamMessageListener); | ||
| 82 | + | ||
| 83 | + this.streamMessageListenerContainer = streamMessageListenerContainer; | ||
| 84 | + // 启动监听 | ||
| 85 | + this.streamMessageListenerContainer.start(); | ||
| 86 | + | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + @Override | ||
| 90 | + public void destroy() throws Exception { | ||
| 91 | + this.streamMessageListenerContainer.stop(); | ||
| 92 | + } | ||
| 93 | +} | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
src/main/java/cn/iocoder/dashboard/modules/system/mq/message/sms/SmsSendMessage.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/stream/sms/SmsSendMessage.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.message.sms; | 1 | +package cn.iocoder.dashboard.modules.system.redis.stream.sms; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.framework.redis.core.pubsub.ChannelMessage; | ||
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 3 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | 5 | ||
| 7 | -import java.util.Collection; | ||
| 8 | -import java.util.List; | ||
| 9 | - | ||
| 10 | /** | 6 | /** |
| 11 | * 部门数据刷新 Message | 7 | * 部门数据刷新 Message |
| 12 | */ | 8 | */ |
| 13 | @Data | 9 | @Data |
| 14 | -public class SmsSendMessage implements ChannelMessage { | 10 | +public class SmsSendMessage { |
| 15 | 11 | ||
| 16 | private SmsBody smsBody; | 12 | private SmsBody smsBody; |
| 17 | 13 | ||
| 18 | - private List<String> targetPhones; | ||
| 19 | - | ||
| 20 | - @Override | ||
| 21 | - public String getChannel() { | ||
| 22 | - return "sms.send"; | ||
| 23 | - } | 14 | + private String targetPhone; |
| 24 | 15 | ||
| 25 | } | 16 | } |
src/main/java/cn/iocoder/dashboard/modules/system/mq/consumer/sms/SmsSendConsumer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/stream/sms/SmsSendStreamConsumer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.consumer.sms; | 1 | +package cn.iocoder.dashboard.modules.system.redis.stream.sms; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.framework.redis.core.pubsub.AbstractChannelMessageListener; | ||
| 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 4 | +import cn.iocoder.dashboard.framework.sms.core.SmsBody; | ||
| 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| 6 | -import cn.iocoder.dashboard.modules.system.mq.message.dept.SysDeptRefreshMessage; | ||
| 7 | -import cn.iocoder.dashboard.modules.system.mq.message.sms.SmsSendMessage; | ||
| 8 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; | 6 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; |
| 9 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; | 7 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; |
| 8 | +import cn.iocoder.dashboard.util.json.JsonUtils; | ||
| 10 | import lombok.extern.slf4j.Slf4j; | 9 | import lombok.extern.slf4j.Slf4j; |
| 10 | +import org.springframework.data.redis.connection.stream.ObjectRecord; | ||
| 11 | +import org.springframework.data.redis.stream.StreamListener; | ||
| 11 | import org.springframework.stereotype.Component; | 12 | import org.springframework.stereotype.Component; |
| 12 | 13 | ||
| 13 | import javax.annotation.Resource; | 14 | import javax.annotation.Resource; |
| 14 | 15 | ||
| 15 | /** | 16 | /** |
| 16 | - * 针对 {@link SysDeptRefreshMessage} 的消费者 | 17 | + * 短信发送流消息监听器 |
| 17 | * | 18 | * |
| 18 | - * @author 芋道源码 | 19 | + * @author zzf |
| 20 | + * @date 2021/3/9 16:35 | ||
| 19 | */ | 21 | */ |
| 20 | -@Component | ||
| 21 | @Slf4j | 22 | @Slf4j |
| 22 | -public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessage> { | 23 | +@Component |
| 24 | +public class SmsSendStreamConsumer implements StreamListener<String, ObjectRecord<String, SmsSendMessage>> { | ||
| 23 | 25 | ||
| 24 | @Resource | 26 | @Resource |
| 25 | private SysSmsChannelService smsChannelService; | 27 | private SysSmsChannelService smsChannelService; |
| @@ -28,14 +30,14 @@ public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessa | @@ -28,14 +30,14 @@ public class SmsSendConsumer extends AbstractChannelMessageListener<SmsSendMessa | ||
| 28 | private SysSmsQueryLogService smsQueryLogService; | 30 | private SysSmsQueryLogService smsQueryLogService; |
| 29 | 31 | ||
| 30 | @Override | 32 | @Override |
| 31 | - public void onMessage(SmsSendMessage message) { | ||
| 32 | - log.info("[onMessage][收到 发送短信 消息], content: " + message.toString()); | ||
| 33 | - AbstractSmsClient smsClient = smsChannelService.getSmsClient(message.getSmsBody().getTemplateCode()); | ||
| 34 | - String templateApiId = smsChannelService.getSmsTemplateApiIdByCode(message.getSmsBody().getTemplateCode()); | ||
| 35 | - | ||
| 36 | - SmsResult result = smsClient.send(templateApiId, message.getSmsBody(), message.getTargetPhones()); | ||
| 37 | - | ||
| 38 | - smsQueryLogService.afterSendLog(message.getSmsBody().getSmsLogId(), result); | 33 | + public void onMessage(ObjectRecord<String, SmsSendMessage> record) { |
| 34 | + SmsSendMessage message = record.getValue(); | ||
| 35 | + SmsBody body = message.getSmsBody(); | ||
| 36 | + log.info("[onMessage][收到 发送短信 消息], content: " + JsonUtils.toJsonString(body)); | ||
| 37 | + AbstractSmsClient smsClient = smsChannelService.getSmsClient(body.getTemplateCode()); | ||
| 38 | + String templateApiId = smsChannelService.getSmsTemplateApiIdByCode(body.getTemplateCode()); | ||
| 39 | + | ||
| 40 | + SmsResult result = smsClient.send(templateApiId, body, message.getTargetPhone()); | ||
| 41 | + smsQueryLogService.afterSendLog(body.getSmsLogId(), result); | ||
| 39 | } | 42 | } |
| 40 | - | ||
| 41 | } | 43 | } |
src/main/java/cn/iocoder/dashboard/modules/system/mq/producer/sms/SmsProducer.java renamed to src/main/java/cn/iocoder/dashboard/modules/system/redis/stream/sms/SmsSendStreamProducer.java
| 1 | -package cn.iocoder.dashboard.modules.system.mq.producer.sms; | 1 | +package cn.iocoder.dashboard.modules.system.redis.stream.sms; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.dashboard.framework.redis.core.util.RedisMessageUtils; | 3 | +import cn.iocoder.dashboard.framework.redis.core.util.RedisStreamUtils; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | -import cn.iocoder.dashboard.modules.system.mq.message.sms.SmsSendMessage; | 5 | +import lombok.extern.slf4j.Slf4j; |
| 6 | import org.springframework.data.redis.core.StringRedisTemplate; | 6 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 7 | import org.springframework.stereotype.Component; | 7 | import org.springframework.stereotype.Component; |
| 8 | 8 | ||
| 9 | import javax.annotation.Resource; | 9 | import javax.annotation.Resource; |
| 10 | -import java.util.List; | ||
| 11 | 10 | ||
| 12 | /** | 11 | /** |
| 13 | - * 短信的 Producer | 12 | + * 短信发送流消息监听器 |
| 13 | + * | ||
| 14 | + * @author zzf | ||
| 15 | + * @date 2021/3/9 16:35 | ||
| 14 | */ | 16 | */ |
| 17 | +@Slf4j | ||
| 15 | @Component | 18 | @Component |
| 16 | -public class SmsProducer { | 19 | +public class SmsSendStreamProducer { |
| 17 | 20 | ||
| 18 | @Resource | 21 | @Resource |
| 19 | private StringRedisTemplate stringRedisTemplate; | 22 | private StringRedisTemplate stringRedisTemplate; |
| @@ -21,12 +24,12 @@ public class SmsProducer { | @@ -21,12 +24,12 @@ public class SmsProducer { | ||
| 21 | /** | 24 | /** |
| 22 | * 发送 {@link SmsSendMessage} 消息 | 25 | * 发送 {@link SmsSendMessage} 消息 |
| 23 | */ | 26 | */ |
| 24 | - public void sendSmsSendMessage(SmsBody smsBody, List<String> targetPhoneList) { | 27 | + public void sendSmsSendMessage(SmsBody smsBody, String targetPhone) { |
| 25 | SmsSendMessage message = new SmsSendMessage(); | 28 | SmsSendMessage message = new SmsSendMessage(); |
| 26 | message.setSmsBody(smsBody); | 29 | message.setSmsBody(smsBody); |
| 27 | - message.setTargetPhones(targetPhoneList); | ||
| 28 | - // TODO FROM 芋艿 TO ZZF:这块等未来改哈。这个方法目前是广播消费,会导致每个节点都发送一次。等后续封装出 redis stream 消息 | ||
| 29 | - RedisMessageUtils.sendChannelMessage(stringRedisTemplate, message); | 30 | + message.setTargetPhone(targetPhone); |
| 31 | + | ||
| 32 | + RedisStreamUtils.sendChannelMessage(stringRedisTemplate, message); | ||
| 30 | } | 33 | } |
| 31 | 34 | ||
| 32 | -} | 35 | -} |
| 36 | +} | ||
| 33 | \ No newline at end of file | 37 | \ No newline at end of file |
src/main/java/cn/iocoder/dashboard/modules/system/service/dept/impl/SysDeptServiceImpl.java
| @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.convert.dept.SysDeptConvert; | @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.convert.dept.SysDeptConvert; | ||
| 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dept.SysDeptMapper; | 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dept.SysDeptMapper; |
| 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; | 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dept.SysDeptDO; |
| 13 | import cn.iocoder.dashboard.modules.system.enums.dept.DeptIdEnum; | 13 | import cn.iocoder.dashboard.modules.system.enums.dept.DeptIdEnum; |
| 14 | -import cn.iocoder.dashboard.modules.system.mq.producer.dept.SysDeptProducer; | 14 | +import cn.iocoder.dashboard.modules.system.redis.mq.producer.dept.SysDeptProducer; |
| 15 | import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; | 15 | import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; |
| 16 | import com.google.common.collect.ImmutableMap; | 16 | import com.google.common.collect.ImmutableMap; |
| 17 | import com.google.common.collect.ImmutableMultimap; | 17 | import com.google.common.collect.ImmutableMultimap; |
src/main/java/cn/iocoder/dashboard/modules/system/service/dict/impl/SysDictDataServiceImpl.java
| @@ -13,7 +13,7 @@ import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert; | @@ -13,7 +13,7 @@ import cn.iocoder.dashboard.modules.system.convert.dict.SysDictDataConvert; | ||
| 13 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dict.SysDictDataMapper; | 13 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.dict.SysDictDataMapper; |
| 14 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; | 14 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictDataDO; |
| 15 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictTypeDO; | 15 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.dict.SysDictTypeDO; |
| 16 | -import cn.iocoder.dashboard.modules.system.mq.producer.dict.SysDictDataProducer; | 16 | +import cn.iocoder.dashboard.modules.system.redis.mq.producer.dict.SysDictDataProducer; |
| 17 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; | 17 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictDataService; |
| 18 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService; | 18 | import cn.iocoder.dashboard.modules.system.service.dict.SysDictTypeService; |
| 19 | import com.google.common.collect.ImmutableTable; | 19 | import com.google.common.collect.ImmutableTable; |
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java
| @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysMenuMappe | @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysMenuMappe | ||
| 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; | 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMenuDO; |
| 12 | import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum; | 12 | import cn.iocoder.dashboard.modules.system.enums.permission.MenuIdEnum; |
| 13 | import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum; | 13 | import cn.iocoder.dashboard.modules.system.enums.permission.MenuTypeEnum; |
| 14 | -import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysMenuProducer; | 14 | +import cn.iocoder.dashboard.modules.system.redis.mq.producer.permission.SysMenuProducer; |
| 15 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; | 15 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; |
| 16 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | 16 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; |
| 17 | import cn.iocoder.dashboard.util.collection.CollectionUtils; | 17 | import cn.iocoder.dashboard.util.collection.CollectionUtils; |
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java
| @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMe | @@ -11,7 +11,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysMe | ||
| 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | 11 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; |
| 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleMenuDO; | 12 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleMenuDO; |
| 13 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysUserRoleDO; | 13 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysUserRoleDO; |
| 14 | -import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysPermissionProducer; | 14 | +import cn.iocoder.dashboard.modules.system.redis.mq.producer.permission.SysPermissionProducer; |
| 15 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; | 15 | import cn.iocoder.dashboard.modules.system.service.permission.SysMenuService; |
| 16 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | 16 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; |
| 17 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; | 17 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; |
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java
| @@ -15,7 +15,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysRoleMappe | @@ -15,7 +15,7 @@ import cn.iocoder.dashboard.modules.system.dal.mysql.dao.permission.SysRoleMappe | ||
| 15 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; | 15 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.permission.SysRoleDO; |
| 16 | import cn.iocoder.dashboard.modules.system.enums.permission.RoleCodeEnum; | 16 | import cn.iocoder.dashboard.modules.system.enums.permission.RoleCodeEnum; |
| 17 | import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum; | 17 | import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum; |
| 18 | -import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysRoleProducer; | 18 | +import cn.iocoder.dashboard.modules.system.redis.mq.producer.permission.SysRoleProducer; |
| 19 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | 19 | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; |
| 20 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; | 20 | import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; |
| 21 | import com.google.common.collect.ImmutableMap; | 21 | import com.google.common.collect.ImmutableMap; |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelService.java
| @@ -2,12 +2,14 @@ package cn.iocoder.dashboard.modules.system.service.sms; | @@ -2,12 +2,14 @@ package cn.iocoder.dashboard.modules.system.service.sms; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.common.pojo.PageResult; | 3 | import cn.iocoder.dashboard.common.pojo.PageResult; |
| 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 5 | +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 5 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO; | 6 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO; |
| 6 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; | 7 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelCreateReqVO; |
| 7 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; | 8 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.req.SmsChannelPageReqVO; |
| 8 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO; | 9 | import cn.iocoder.dashboard.modules.system.controller.sms.vo.resp.SmsChannelEnumRespVO; |
| 9 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO; | 10 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsChannelDO; |
| 10 | 11 | ||
| 12 | +import javax.servlet.ServletRequest; | ||
| 11 | import java.util.List; | 13 | import java.util.List; |
| 12 | 14 | ||
| 13 | /** | 15 | /** |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsQueryLogService.java
| @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.service.sms; | @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.service.sms; | ||
| 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| 6 | +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 6 | 7 | ||
| 7 | import java.util.List; | 8 | import java.util.List; |
| 8 | 9 | ||
| @@ -16,16 +17,16 @@ public interface SysSmsQueryLogService { | @@ -16,16 +17,16 @@ public interface SysSmsQueryLogService { | ||
| 16 | /** | 17 | /** |
| 17 | * 发送短信前的日志处理 | 18 | * 发送短信前的日志处理 |
| 18 | * | 19 | * |
| 19 | - * @param smsBody 短信内容 | ||
| 20 | - * @param targetPhones 发送对象手机号集合 | ||
| 21 | - * @param client 短信客户端 | 20 | + * @param smsBody 短信内容 |
| 21 | + * @param targetPhone 发送对象手机号 | ||
| 22 | + * @param client 短信客户端 | ||
| 22 | * @return 生成的日志id | 23 | * @return 生成的日志id |
| 23 | */ | 24 | */ |
| 24 | // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果. | 25 | // TODO FROM 芋艿 to ZZF: async 是针对发送的方式,对于日志不一定需要关心。这样,短信日志,实际就发送前插入,发送后更新结果. |
| 25 | // 这里只用于记录状态,毕竟异步可能推送失败,此时日志可记录该状态。 | 26 | // 这里只用于记录状态,毕竟异步可能推送失败,此时日志可记录该状态。 |
| 26 | 27 | ||
| 27 | // TODO FROM 芋艿 to ZZF:短信日志,群发的情况,应该是每个手机一条哈。虽然是群发,但是可能部分成功,部分失败;对应到短信平台,实际也是多条。 | 28 | // TODO FROM 芋艿 to ZZF:短信日志,群发的情况,应该是每个手机一条哈。虽然是群发,但是可能部分成功,部分失败;对应到短信平台,实际也是多条。 |
| 28 | - void beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client); | 29 | + void beforeSendLog(SmsBody smsBody, String targetPhone, AbstractSmsClient client); |
| 29 | 30 | ||
| 30 | /** | 31 | /** |
| 31 | * 发送消息后的日志处理 | 32 | * 发送消息后的日志处理 |
| @@ -35,4 +36,5 @@ public interface SysSmsQueryLogService { | @@ -35,4 +36,5 @@ public interface SysSmsQueryLogService { | ||
| 35 | */ | 36 | */ |
| 36 | void afterSendLog(Long logId, SmsResult result); | 37 | void afterSendLog(Long logId, SmsResult result); |
| 37 | 38 | ||
| 39 | + void updateSendLogByResultDetail(SmsResultDetail smsResultDetail); | ||
| 38 | } | 40 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java
| 1 | package cn.iocoder.dashboard.modules.system.service.sms; | 1 | package cn.iocoder.dashboard.modules.system.service.sms; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | +import cn.hutool.core.util.ArrayUtil; | ||
| 3 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 6 | +import cn.iocoder.dashboard.framework.sms.core.enums.SmsChannelEnum; | ||
| 4 | 7 | ||
| 5 | import javax.servlet.ServletRequest; | 8 | import javax.servlet.ServletRequest; |
| 6 | import java.util.Arrays; | 9 | import java.util.Arrays; |
| 7 | -import java.util.Collections; | ||
| 8 | import java.util.List; | 10 | import java.util.List; |
| 9 | 11 | ||
| 10 | /** | 12 | /** |
| @@ -22,7 +24,12 @@ public interface SysSmsService { | @@ -22,7 +24,12 @@ public interface SysSmsService { | ||
| 22 | * @param smsBody 消息内容 | 24 | * @param smsBody 消息内容 |
| 23 | * @param targetPhones 发送对象手机号列表 | 25 | * @param targetPhones 发送对象手机号列表 |
| 24 | */ | 26 | */ |
| 25 | - void send(SmsBody smsBody, List<String> targetPhones); | 27 | + default void send(SmsBody smsBody, List<String> targetPhones) { |
| 28 | + if (CollectionUtil.isEmpty(targetPhones)) { | ||
| 29 | + return; | ||
| 30 | + } | ||
| 31 | + targetPhones.forEach(s -> this.send(smsBody, s)); | ||
| 32 | + } | ||
| 26 | 33 | ||
| 27 | /** | 34 | /** |
| 28 | * 发送消息 | 35 | * 发送消息 |
| @@ -30,9 +37,7 @@ public interface SysSmsService { | @@ -30,9 +37,7 @@ public interface SysSmsService { | ||
| 30 | * @param smsBody 消息内容 | 37 | * @param smsBody 消息内容 |
| 31 | * @param targetPhone 发送对象手机号 | 38 | * @param targetPhone 发送对象手机号 |
| 32 | */ | 39 | */ |
| 33 | - default void send(SmsBody smsBody, String targetPhone) { | ||
| 34 | - send(smsBody, Collections.singletonList(targetPhone)); | ||
| 35 | - } | 40 | + void send(SmsBody smsBody, String targetPhone); |
| 36 | 41 | ||
| 37 | /** | 42 | /** |
| 38 | * 发送消息 | 43 | * 发送消息 |
| @@ -41,14 +46,18 @@ public interface SysSmsService { | @@ -41,14 +46,18 @@ public interface SysSmsService { | ||
| 41 | * @param targetPhones 发送对象手机号数组 | 46 | * @param targetPhones 发送对象手机号数组 |
| 42 | */ | 47 | */ |
| 43 | default void send(SmsBody smsBody, String... targetPhones) { | 48 | default void send(SmsBody smsBody, String... targetPhones) { |
| 49 | + if (ArrayUtil.isEmpty(targetPhones)) { | ||
| 50 | + return; | ||
| 51 | + } | ||
| 44 | send(smsBody, Arrays.asList(targetPhones)); | 52 | send(smsBody, Arrays.asList(targetPhones)); |
| 45 | } | 53 | } |
| 46 | 54 | ||
| 47 | /** | 55 | /** |
| 48 | * 处理短信发送回调函数 | 56 | * 处理短信发送回调函数 |
| 49 | * | 57 | * |
| 50 | - * @param request 请求 | 58 | + * @param request 请求 |
| 51 | * @return 响应数据 | 59 | * @return 响应数据 |
| 52 | */ | 60 | */ |
| 53 | Object smsSendCallbackHandle(ServletRequest request); | 61 | Object smsSendCallbackHandle(ServletRequest request); |
| 62 | + | ||
| 54 | } | 63 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsQueryLogServiceImpl.java
| @@ -3,16 +3,15 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | @@ -3,16 +3,15 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | ||
| 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResult; |
| 6 | +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 6 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; | 7 | import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty; |
| 7 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper; | 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper; |
| 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsQueryLogDO; | 9 | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.sms.SysSmsQueryLogDO; |
| 9 | import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum; | 10 | import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum; |
| 10 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; | 11 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; |
| 11 | -import cn.iocoder.dashboard.util.json.JsonUtils; | ||
| 12 | import org.springframework.stereotype.Service; | 12 | import org.springframework.stereotype.Service; |
| 13 | 13 | ||
| 14 | import javax.annotation.Resource; | 14 | import javax.annotation.Resource; |
| 15 | -import java.util.List; | ||
| 16 | 15 | ||
| 17 | /** | 16 | /** |
| 18 | * 短信请求日志服务实现类 | 17 | * 短信请求日志服务实现类 |
| @@ -27,14 +26,14 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService { | @@ -27,14 +26,14 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService { | ||
| 27 | private SysSmsQueryLogMapper logMapper; | 26 | private SysSmsQueryLogMapper logMapper; |
| 28 | 27 | ||
| 29 | @Override | 28 | @Override |
| 30 | - public void beforeSendLog(SmsBody smsBody, List<String> targetPhones, AbstractSmsClient client) { | 29 | + public void beforeSendLog(SmsBody smsBody, String targetPhone, AbstractSmsClient client) { |
| 31 | SysSmsQueryLogDO smsLog = new SysSmsQueryLogDO(); | 30 | SysSmsQueryLogDO smsLog = new SysSmsQueryLogDO(); |
| 32 | SmsChannelProperty property = client.getProperty(); | 31 | SmsChannelProperty property = client.getProperty(); |
| 33 | 32 | ||
| 34 | smsLog.setChannelCode(property.getCode()) | 33 | smsLog.setChannelCode(property.getCode()) |
| 35 | .setChannelId(property.getId()) | 34 | .setChannelId(property.getId()) |
| 36 | .setTemplateCode(smsBody.getTemplateCode()) | 35 | .setTemplateCode(smsBody.getTemplateCode()) |
| 37 | - .setPhones(targetPhones) | 36 | + .setPhone(targetPhone) |
| 38 | .setContent(smsBody.getParams().toString()); | 37 | .setContent(smsBody.getParams().toString()); |
| 39 | 38 | ||
| 40 | smsLog.setSendStatus(SmsSendStatusEnum.ASYNC.getStatus()); | 39 | smsLog.setSendStatus(SmsSendStatusEnum.ASYNC.getStatus()); |
| @@ -46,14 +45,19 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService { | @@ -46,14 +45,19 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService { | ||
| 46 | public void afterSendLog(Long logId, SmsResult result) { | 45 | public void afterSendLog(Long logId, SmsResult result) { |
| 47 | SysSmsQueryLogDO smsLog = new SysSmsQueryLogDO(); | 46 | SysSmsQueryLogDO smsLog = new SysSmsQueryLogDO(); |
| 48 | smsLog.setId(logId); | 47 | smsLog.setId(logId); |
| 49 | - if (result.getSuccess()) { | ||
| 50 | - smsLog.setSendStatus(SmsSendStatusEnum.QUERY_SUCCESS.getStatus()); | ||
| 51 | - smsLog.setSendResultParam(result.getSendResultParam()); | ||
| 52 | - } else { | ||
| 53 | - smsLog.setSendStatus(SmsSendStatusEnum.QUERY_FAIL.getStatus()); | ||
| 54 | - smsLog.setRemark(result.getMessage()); | ||
| 55 | - } | 48 | + smsLog.setApiId(result.getApiId()); |
| 49 | + smsLog.setSendStatus(SmsSendStatusEnum.QUERY_FAIL.getStatus()); | ||
| 50 | + smsLog.setRemark(result.getCode() + ": " + result.getMessage()); | ||
| 56 | logMapper.updateById(smsLog); | 51 | logMapper.updateById(smsLog); |
| 57 | } | 52 | } |
| 58 | 53 | ||
| 54 | + @Override | ||
| 55 | + public void updateSendLogByResultDetail(SmsResultDetail smsResultDetail) { | ||
| 56 | + SysSmsQueryLogDO queryLogDO = new SysSmsQueryLogDO(); | ||
| 57 | + queryLogDO.setSendStatus(smsResultDetail.getSendStatus()); | ||
| 58 | + queryLogDO.setSendTime(smsResultDetail.getSendTime()); | ||
| 59 | + queryLogDO.setRemark(smsResultDetail.getMessage()); | ||
| 60 | + logMapper.updateByApiId(queryLogDO, smsResultDetail.getApiId()); | ||
| 61 | + } | ||
| 62 | + | ||
| 59 | } | 63 | } |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java
| @@ -2,7 +2,6 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | @@ -2,7 +2,6 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollectionUtil; | 3 | import cn.hutool.core.collection.CollectionUtil; |
| 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 4 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 5 | -import cn.iocoder.dashboard.framework.sms.client.NeedQuerySendResultSmsClient; | ||
| 6 | import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | 5 | import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; |
| 7 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper; | 6 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper; |
| 8 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsSendLogMapper; | 7 | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsSendLogMapper; |
| @@ -62,7 +61,7 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { | @@ -62,7 +61,7 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { | ||
| 62 | updateQueryLog.setId(queryLog.getId()); | 61 | updateQueryLog.setId(queryLog.getId()); |
| 63 | 62 | ||
| 64 | // 只处理实现了获取发送结果方法的短信客户端,理论上这里都是满足条件的,以防万一加个判断。 | 63 | // 只处理实现了获取发送结果方法的短信客户端,理论上这里都是满足条件的,以防万一加个判断。 |
| 65 | - if (smsClient instanceof NeedQuerySendResultSmsClient) { | 64 | + /*if (smsClient instanceof NeedQuerySendResultSmsClient) { |
| 66 | //初始化点字段值 | 65 | //初始化点字段值 |
| 67 | queryLog2SendLong(insertSendLog, queryLog); | 66 | queryLog2SendLong(insertSendLog, queryLog); |
| 68 | 67 | ||
| @@ -89,7 +88,7 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { | @@ -89,7 +88,7 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService { | ||
| 89 | //理论上这里都是满足条件的,以防万一加个判断。 | 88 | //理论上这里都是满足条件的,以防万一加个判断。 |
| 90 | updateQueryLog.setSendStatus(SmsSendStatusEnum.QUERY_SEND_FAIL.getStatus()); | 89 | updateQueryLog.setSendStatus(SmsSendStatusEnum.QUERY_SEND_FAIL.getStatus()); |
| 91 | smsQueryLogMapper.updateById(updateQueryLog); | 90 | smsQueryLogMapper.updateById(updateQueryLog); |
| 92 | - } | 91 | + }*/ |
| 93 | updateQueryLog.setSendStatus(SmsSendStatusEnum.SEND_SUCCESS.getStatus()); | 92 | updateQueryLog.setSendStatus(SmsSendStatusEnum.SEND_SUCCESS.getStatus()); |
| 94 | updateQueryLog.setRemark(String.format("日志(id = %s)对应的客户端没有继承NeedQuerySendResultSmsClient, 不能获取短信结果。", queryLog.getId())); | 93 | updateQueryLog.setRemark(String.format("日志(id = %s)对应的客户端没有继承NeedQuerySendResultSmsClient, 不能获取短信结果。", queryLog.getId())); |
| 95 | smsQueryLogMapper.updateById(updateQueryLog); | 94 | smsQueryLogMapper.updateById(updateQueryLog); |
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java
| @@ -2,15 +2,16 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | @@ -2,15 +2,16 @@ package cn.iocoder.dashboard.modules.system.service.sms.impl; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; | 3 | import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient; |
| 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; | 4 | import cn.iocoder.dashboard.framework.sms.core.SmsBody; |
| 5 | -import cn.iocoder.dashboard.modules.system.mq.producer.sms.SmsProducer; | 5 | +import cn.iocoder.dashboard.framework.sms.core.SmsClientFactory; |
| 6 | +import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail; | ||
| 7 | +import cn.iocoder.dashboard.modules.system.redis.stream.sms.SmsSendStreamProducer; | ||
| 6 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; | 8 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; |
| 7 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; | 9 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService; |
| 8 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; | 10 | import cn.iocoder.dashboard.modules.system.service.sms.SysSmsService; |
| 9 | -import org.springframework.scheduling.annotation.Scheduled; | ||
| 10 | import org.springframework.stereotype.Service; | 11 | import org.springframework.stereotype.Service; |
| 11 | 12 | ||
| 12 | import javax.annotation.Resource; | 13 | import javax.annotation.Resource; |
| 13 | -import java.util.List; | 14 | +import javax.servlet.ServletRequest; |
| 14 | 15 | ||
| 15 | /** | 16 | /** |
| 16 | * 短信日志Service实现类 | 17 | * 短信日志Service实现类 |
| @@ -28,15 +29,23 @@ public class SysSmsServiceImpl implements SysSmsService { | @@ -28,15 +29,23 @@ public class SysSmsServiceImpl implements SysSmsService { | ||
| 28 | private SysSmsQueryLogService logService; | 29 | private SysSmsQueryLogService logService; |
| 29 | 30 | ||
| 30 | @Resource | 31 | @Resource |
| 31 | - private SmsProducer smsProducer; | 32 | + private SmsSendStreamProducer smsProducer; |
| 33 | + | ||
| 34 | + @Resource | ||
| 35 | + private SmsClientFactory smsClientFactory; | ||
| 32 | 36 | ||
| 33 | @Override | 37 | @Override |
| 34 | - public void send(SmsBody smsBody, List<String> targetPhones) { | 38 | + public void send(SmsBody smsBody, String targetPhone) { |
| 35 | AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode()); | 39 | AbstractSmsClient client = channelService.getSmsClient(smsBody.getTemplateCode()); |
| 36 | - logService.beforeSendLog(smsBody, targetPhones, client); | ||
| 37 | - smsProducer.sendSmsSendMessage(smsBody, targetPhones); | 40 | + logService.beforeSendLog(smsBody, targetPhone, client); |
| 41 | + smsProducer.sendSmsSendMessage(smsBody, targetPhone); | ||
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | - // TODO FROM 芋艿 to ZZF:可能要讨论下,对于短信发送来说,貌似只提供异步发送即可。对于业务来说,一定不能依赖短信的发送结果. | 44 | + @Override |
| 45 | + public Object smsSendCallbackHandle(ServletRequest request) { | ||
| 46 | + SmsResultDetail smsResultDetail = smsClientFactory.getSmsResultDetailFromCallbackQuery(request); | ||
| 47 | + logService.updateSendLogByResultDetail(smsResultDetail); | ||
| 48 | + return smsResultDetail.getCallbackResponseBody(); | ||
| 49 | + } | ||
| 41 | 50 | ||
| 42 | } | 51 | } |