Commit 9f794ecb1593c025193bb665bcfaf333a7524aaf

Authored by YunaiV
1 parent f4aba034

1. 创建和修改短信模板时,接入 API 短信模板的校验

src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java
@@ -77,8 +77,7 @@ public class SysSmsServiceImpl implements SysSmsService { @@ -77,8 +77,7 @@ public class SysSmsServiceImpl implements SysSmsService {
77 @Override 77 @Override
78 public void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType, 78 public void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType,
79 String templateCode, Map<String, Object> templateParams) { 79 String templateCode, Map<String, Object> templateParams) {
80 - // 校验短信模板是否存在  
81 - SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode); 80 + throw new IllegalArgumentException("暂时不支持该操作,感兴趣可以实现该功能哟!");
82 } 81 }
83 82
84 private SysSmsTemplateDO checkSmsTemplateValid(String templateCode) { 83 private SysSmsTemplateDO checkSmsTemplateValid(String templateCode) {
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java
@@ -4,6 +4,10 @@ import cn.hutool.core.util.ReUtil; @@ -4,6 +4,10 @@ import cn.hutool.core.util.ReUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 5 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
6 import cn.iocoder.dashboard.common.pojo.PageResult; 6 import cn.iocoder.dashboard.common.pojo.PageResult;
  7 +import cn.iocoder.dashboard.framework.sms.core.client.SmsClient;
  8 +import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
  9 +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
  10 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
7 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO; 11 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO;
8 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateExportReqVO; 12 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateExportReqVO;
9 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplatePageReqVO; 13 import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplatePageReqVO;
@@ -16,6 +20,8 @@ import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; @@ -16,6 +20,8 @@ import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
16 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService; 20 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService;
17 import com.google.common.annotations.VisibleForTesting; 21 import com.google.common.annotations.VisibleForTesting;
18 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
  23 +import org.springframework.util.Assert;
  24 +import org.springframework.validation.annotation.Validated;
19 25
20 import javax.annotation.Resource; 26 import javax.annotation.Resource;
21 import java.util.Collection; 27 import java.util.Collection;
@@ -34,6 +40,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; @@ -34,6 +40,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
34 * @date 2021/1/25 9:25 40 * @date 2021/1/25 9:25
35 */ 41 */
36 @Service 42 @Service
  43 +@Validated
37 public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { 44 public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
38 45
39 /** 46 /**
@@ -47,6 +54,9 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { @@ -47,6 +54,9 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
47 @Resource 54 @Resource
48 private SysSmsChannelService smsChannelService; 55 private SysSmsChannelService smsChannelService;
49 56
  57 + @Resource
  58 + private SmsClientFactory smsClientFactory;
  59 +
50 @Override 60 @Override
51 public SysSmsTemplateDO getSmsTemplateByCode(String code) { 61 public SysSmsTemplateDO getSmsTemplateByCode(String code) {
52 return smsTemplateMapper.selectByCode(code); 62 return smsTemplateMapper.selectByCode(code);
@@ -68,6 +78,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { @@ -68,6 +78,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
68 SysSmsChannelDO channelDO = checkSmsChannel(createReqVO.getChannelId()); 78 SysSmsChannelDO channelDO = checkSmsChannel(createReqVO.getChannelId());
69 // 校验短信编码是否重复 79 // 校验短信编码是否重复
70 checkSmsTemplateCodeDuplicate(null, createReqVO.getCode()); 80 checkSmsTemplateCodeDuplicate(null, createReqVO.getCode());
  81 + // 校验短信模板
  82 + checkApiTemplate(createReqVO.getChannelId(), createReqVO.getApiTemplateId());
71 83
72 // 插入 84 // 插入
73 SysSmsTemplateDO template = SysSmsTemplateConvert.INSTANCE.convert(createReqVO); 85 SysSmsTemplateDO template = SysSmsTemplateConvert.INSTANCE.convert(createReqVO);
@@ -86,6 +98,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { @@ -86,6 +98,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
86 SysSmsChannelDO channelDO = checkSmsChannel(updateReqVO.getChannelId()); 98 SysSmsChannelDO channelDO = checkSmsChannel(updateReqVO.getChannelId());
87 // 校验短信编码是否重复 99 // 校验短信编码是否重复
88 checkSmsTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); 100 checkSmsTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode());
  101 + // 校验短信模板
  102 + checkApiTemplate(updateReqVO.getChannelId(), updateReqVO.getApiTemplateId());
89 103
90 // 更新 104 // 更新
91 SysSmsTemplateDO updateObj = SysSmsTemplateConvert.INSTANCE.convert(updateReqVO); 105 SysSmsTemplateDO updateObj = SysSmsTemplateConvert.INSTANCE.convert(updateReqVO);
@@ -155,4 +169,20 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { @@ -155,4 +169,20 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService {
155 } 169 }
156 } 170 }
157 171
  172 + /**
  173 + * 校验 API 短信平台的模板是否有效
  174 + *
  175 + * @param channelId 渠道编号
  176 + * @param apiTemplateId API 模板编号
  177 + */
  178 + @VisibleForTesting
  179 + public void checkApiTemplate(Long channelId, String apiTemplateId) {
  180 + // 获得短信模板
  181 + SmsClient smsClient = smsClientFactory.getSmsClient(channelId);
  182 + Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", channelId));
  183 + SmsCommonResult<SmsTemplateRespDTO> templateResult = smsClient.getSmsTemplate(apiTemplateId);
  184 + // 校验短信模板是否正确
  185 + templateResult.checkError();
  186 + }
  187 +
158 } 188 }
src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateServiceTest.java
@@ -2,8 +2,16 @@ package cn.iocoder.dashboard.modules.system.service.sms; @@ -2,8 +2,16 @@ package cn.iocoder.dashboard.modules.system.service.sms;
2 2
3 import cn.iocoder.dashboard.BaseDbUnitTest; 3 import cn.iocoder.dashboard.BaseDbUnitTest;
4 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 4 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants;
5 import cn.iocoder.dashboard.common.pojo.PageResult; 6 import cn.iocoder.dashboard.common.pojo.PageResult;
6 -import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.*; 7 +import cn.iocoder.dashboard.framework.sms.core.client.SmsClient;
  8 +import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory;
  9 +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult;
  10 +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO;
  11 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO;
  12 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateExportReqVO;
  13 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplatePageReqVO;
  14 +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateUpdateReqVO;
7 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; 15 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO;
8 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; 16 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
9 import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsTemplateMapper; 17 import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsTemplateMapper;
@@ -47,6 +55,11 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @@ -47,6 +55,11 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
47 @MockBean 55 @MockBean
48 private SysSmsChannelService smsChannelService; 56 private SysSmsChannelService smsChannelService;
49 57
  58 + @MockBean
  59 + private SmsClientFactory smsClientFactory;
  60 + @MockBean
  61 + private SmsClient smsClient;
  62 +
50 @Test 63 @Test
51 public void testParseTemplateContentParams() { 64 public void testParseTemplateContentParams() {
52 // 准备参数 65 // 准备参数
@@ -60,6 +73,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @@ -60,6 +73,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
60 } 73 }
61 74
62 @Test 75 @Test
  76 + @SuppressWarnings("unchecked")
63 public void testCreateSmsTemplate_success() { 77 public void testCreateSmsTemplate_success() {
64 // 准备参数 78 // 准备参数
65 SysSmsTemplateCreateReqVO reqVO = randomPojo(SysSmsTemplateCreateReqVO.class, o -> { 79 SysSmsTemplateCreateReqVO reqVO = randomPojo(SysSmsTemplateCreateReqVO.class, o -> {
@@ -67,12 +81,16 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @@ -67,12 +81,16 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
67 o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 81 o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
68 o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的泛微 82 o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的泛微
69 }); 83 });
70 - // mock 方法 84 + // mock Channel 的方法
71 SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> { 85 SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> {
72 o.setId(reqVO.getChannelId()); 86 o.setId(reqVO.getChannelId());
73 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态 87 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
74 }); 88 });
75 when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); 89 when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
  90 + // mock 获得 API 短信模板成功
  91 + when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
  92 + when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class,
  93 + o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode())));
76 94
77 // 调用 95 // 调用
78 Long smsTemplateId = smsTemplateService.createSmsTemplate(reqVO); 96 Long smsTemplateId = smsTemplateService.createSmsTemplate(reqVO);
@@ -86,6 +104,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @@ -86,6 +104,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
86 } 104 }
87 105
88 @Test 106 @Test
  107 + @SuppressWarnings("unchecked")
89 public void testUpdateSmsTemplate_success() { 108 public void testUpdateSmsTemplate_success() {
90 // mock 数据 109 // mock 数据
91 SysSmsTemplateDO dbSmsTemplate = randomSmsTemplateDO(); 110 SysSmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
@@ -103,6 +122,10 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @@ -103,6 +122,10 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
103 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态 122 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
104 }); 123 });
105 when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); 124 when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
  125 + // mock 获得 API 短信模板成功
  126 + when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
  127 + when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class,
  128 + o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode())));
106 129
107 // 调用 130 // 调用
108 smsTemplateService.updateSmsTemplate(reqVO); 131 smsTemplateService.updateSmsTemplate(reqVO);
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java
@@ -7,6 +7,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; @@ -7,6 +7,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
7 import uk.co.jemos.podam.api.PodamFactory; 7 import uk.co.jemos.podam.api.PodamFactory;
8 import uk.co.jemos.podam.api.PodamFactoryImpl; 8 import uk.co.jemos.podam.api.PodamFactoryImpl;
9 9
  10 +import java.lang.reflect.Type;
10 import java.util.Arrays; 11 import java.util.Arrays;
11 import java.util.Date; 12 import java.util.Date;
12 import java.util.Set; 13 import java.util.Set;
@@ -87,4 +88,14 @@ public class RandomUtils { @@ -87,4 +88,14 @@ public class RandomUtils {
87 return pojo; 88 return pojo;
88 } 89 }
89 90
  91 + @SafeVarargs
  92 + public static <T> T randomPojo(Class<T> clazz, Type type, Consumer<T>... consumers) {
  93 + T pojo = PODAM_FACTORY.manufacturePojo(clazz, type);
  94 + // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
  95 + if (ArrayUtil.isNotEmpty(consumers)) {
  96 + Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
  97 + }
  98 + return pojo;
  99 + }
  100 +
90 } 101 }