Commit 9f794ecb1593c025193bb665bcfaf333a7524aaf
1 parent
f4aba034
1. 创建和修改短信模板时,接入 API 短信模板的校验
Showing
4 changed files
with
67 additions
and
4 deletions
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 | } |