diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java index c5a12797f..1ccb090cd 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java @@ -77,8 +77,7 @@ public class SysSmsServiceImpl implements SysSmsService { @Override public void sendBatchSms(List mobiles, List userIds, Integer userType, String templateCode, Map templateParams) { - // 校验短信模板是否存在 - SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode); + throw new IllegalArgumentException("暂时不支持该操作,感兴趣可以实现该功能哟!"); } private SysSmsTemplateDO checkSmsTemplateValid(String templateCode) { diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java index f3e50547d..fc1c0dc5f 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsTemplateServiceImpl.java @@ -4,6 +4,10 @@ import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.dashboard.common.enums.CommonStatusEnum; import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.framework.sms.core.client.SmsClient; +import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory; +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateExportReqVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplatePageReqVO; @@ -16,6 +20,8 @@ import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService; import cn.iocoder.dashboard.modules.system.service.sms.SysSmsTemplateService; import com.google.common.annotations.VisibleForTesting; import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.util.Collection; @@ -34,6 +40,7 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; * @date 2021/1/25 9:25 */ @Service +@Validated public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { /** @@ -47,6 +54,9 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { @Resource private SysSmsChannelService smsChannelService; + @Resource + private SmsClientFactory smsClientFactory; + @Override public SysSmsTemplateDO getSmsTemplateByCode(String code) { return smsTemplateMapper.selectByCode(code); @@ -68,6 +78,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { SysSmsChannelDO channelDO = checkSmsChannel(createReqVO.getChannelId()); // 校验短信编码是否重复 checkSmsTemplateCodeDuplicate(null, createReqVO.getCode()); + // 校验短信模板 + checkApiTemplate(createReqVO.getChannelId(), createReqVO.getApiTemplateId()); // 插入 SysSmsTemplateDO template = SysSmsTemplateConvert.INSTANCE.convert(createReqVO); @@ -86,6 +98,8 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { SysSmsChannelDO channelDO = checkSmsChannel(updateReqVO.getChannelId()); // 校验短信编码是否重复 checkSmsTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode()); + // 校验短信模板 + checkApiTemplate(updateReqVO.getChannelId(), updateReqVO.getApiTemplateId()); // 更新 SysSmsTemplateDO updateObj = SysSmsTemplateConvert.INSTANCE.convert(updateReqVO); @@ -155,4 +169,20 @@ public class SysSmsTemplateServiceImpl implements SysSmsTemplateService { } } + /** + * 校验 API 短信平台的模板是否有效 + * + * @param channelId 渠道编号 + * @param apiTemplateId API 模板编号 + */ + @VisibleForTesting + public void checkApiTemplate(Long channelId, String apiTemplateId) { + // 获得短信模板 + SmsClient smsClient = smsClientFactory.getSmsClient(channelId); + Assert.notNull(smsClient, String.format("短信客户端(%d) 不存在", channelId)); + SmsCommonResult templateResult = smsClient.getSmsTemplate(apiTemplateId); + // 校验短信模板是否正确 + templateResult.checkError(); + } + } diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateServiceTest.java index 7e79d3aa7..51db4bed0 100644 --- a/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateServiceTest.java +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsTemplateServiceTest.java @@ -2,8 +2,16 @@ package cn.iocoder.dashboard.modules.system.service.sms; import cn.iocoder.dashboard.BaseDbUnitTest; import cn.iocoder.dashboard.common.enums.CommonStatusEnum; +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.dashboard.common.pojo.PageResult; -import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.*; +import cn.iocoder.dashboard.framework.sms.core.client.SmsClient; +import cn.iocoder.dashboard.framework.sms.core.client.SmsClientFactory; +import cn.iocoder.dashboard.framework.sms.core.client.SmsCommonResult; +import cn.iocoder.dashboard.framework.sms.core.client.dto.SmsTemplateRespDTO; +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO; +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateExportReqVO; +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplatePageReqVO; +import cn.iocoder.dashboard.modules.system.controller.sms.vo.template.SysSmsTemplateUpdateReqVO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsChannelDO; import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsTemplateDO; import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsTemplateMapper; @@ -47,6 +55,11 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { @MockBean private SysSmsChannelService smsChannelService; + @MockBean + private SmsClientFactory smsClientFactory; + @MockBean + private SmsClient smsClient; + @Test public void testParseTemplateContentParams() { // 准备参数 @@ -60,6 +73,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { } @Test + @SuppressWarnings("unchecked") public void testCreateSmsTemplate_success() { // 准备参数 SysSmsTemplateCreateReqVO reqVO = randomPojo(SysSmsTemplateCreateReqVO.class, o -> { @@ -67,12 +81,16 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围 o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的泛微 }); - // mock 方法 + // mock Channel 的方法 SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> { o.setId(reqVO.getChannelId()); o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态 }); when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); + // mock 获得 API 短信模板成功 + when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); + when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, + o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); // 调用 Long smsTemplateId = smsTemplateService.createSmsTemplate(reqVO); @@ -86,6 +104,7 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { } @Test + @SuppressWarnings("unchecked") public void testUpdateSmsTemplate_success() { // mock 数据 SysSmsTemplateDO dbSmsTemplate = randomSmsTemplateDO(); @@ -103,6 +122,10 @@ public class SysSmsTemplateServiceTest extends BaseDbUnitTest { o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态 }); when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO); + // mock 获得 API 短信模板成功 + when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient); + when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class, + o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode()))); // 调用 smsTemplateService.updateSmsTemplate(reqVO); diff --git a/src/test/java/cn/iocoder/dashboard/util/RandomUtils.java b/src/test/java/cn/iocoder/dashboard/util/RandomUtils.java index c668f980c..1979e091f 100644 --- a/src/test/java/cn/iocoder/dashboard/util/RandomUtils.java +++ b/src/test/java/cn/iocoder/dashboard/util/RandomUtils.java @@ -7,6 +7,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; +import java.lang.reflect.Type; import java.util.Arrays; import java.util.Date; import java.util.Set; @@ -87,4 +88,14 @@ public class RandomUtils { return pojo; } + @SafeVarargs + public static T randomPojo(Class clazz, Type type, Consumer... consumers) { + T pojo = PODAM_FACTORY.manufacturePojo(clazz, type); + // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理 + if (ArrayUtil.isNotEmpty(consumers)) { + Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo)); + } + return pojo; + } + }