Browse Source

短信提交 2021-03-25,调整下短信发送 API

YunaiV 4 years ago
parent
commit
df01bd6c79
16 changed files with 216 additions and 116 deletions
  1. 3 3
      src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/ali/AliyunSmsClient.java
  2. 3 3
      src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/yunpian/YunpianSmsClient.java
  3. 2 1
      src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java
  4. 80 30
      src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsQueryLogDO.java
  5. 2 2
      src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java
  6. 25 27
      src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsTemplateDO.java
  7. 2 2
      src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsQueryLogMapper.java
  8. 1 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java
  9. 0 39
      src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SmsSendStatusEnum.java
  10. 19 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java
  11. 23 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendStatusEnum.java
  12. 25 0
      src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsTemplateTypeEnum.java
  13. 2 0
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java
  14. 3 3
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsQueryLogServiceImpl.java
  15. 2 2
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java
  16. 24 4
      src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java

+ 3 - 3
src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/ali/AliyunSmsClient.java

@@ -7,7 +7,7 @@ import cn.iocoder.dashboard.framework.sms.core.SmsBody;
 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import cn.iocoder.dashboard.util.json.JsonUtils;
 import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.IAcsClient;
@@ -131,8 +131,8 @@ public class AliyunSmsClient extends AbstractSmsClient {
 
         public Integer getSendStatus() {
             return ((Boolean) sendResultParamMap.get(CallbackField.SUCCESS))
-                    ? SmsSendStatusEnum.SEND_SUCCESS.getStatus()
-                    : SmsSendStatusEnum.SEND_FAIL.getStatus();
+                    ? SysSmsSendStatusEnum.SEND_SUCCESS.getStatus()
+                    : SysSmsSendStatusEnum.SEND_FAIL.getStatus();
         }
 
         public String getBizId() {

+ 3 - 3
src/main/java/cn/iocoder/dashboard/framework/sms/client/impl/yunpian/YunpianSmsClient.java

@@ -9,7 +9,7 @@ import cn.iocoder.dashboard.framework.sms.core.SmsConstants;
 import cn.iocoder.dashboard.framework.sms.core.SmsResult;
 import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import cn.iocoder.dashboard.util.json.JsonUtils;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.yunpian.sdk.YunpianClient;
@@ -155,8 +155,8 @@ public class YunpianSmsClient extends AbstractSmsClient {
         private static int getSendStatus(Map<String, String> map) {
             String reportStatus = map.get(REPORT_STATUS);
             return SmsConstants.SUCCESS.equals(reportStatus)
-                    ? SmsSendStatusEnum.SEND_SUCCESS.getStatus()
-                    : SmsSendStatusEnum.SEND_FAIL.getStatus();
+                    ? SysSmsSendStatusEnum.SEND_SUCCESS.getStatus()
+                    : SysSmsSendStatusEnum.SEND_FAIL.getStatus();
         }
 
         public static SmsResultDetail getSmsResultDetailByParam(Map<String, String> map) {

+ 2 - 1
src/main/java/cn/iocoder/dashboard/framework/sms/core/SmsResultDetail.java

@@ -1,5 +1,6 @@
 package cn.iocoder.dashboard.framework.sms.core;
 
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import lombok.Data;
 
 import java.io.Serializable;
@@ -17,7 +18,7 @@ public class SmsResultDetail implements Serializable {
     private String apiId;
 
     /**
-     * 短信发送状态 {@link cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum}
+     * 短信发送状态 {@link SysSmsSendStatusEnum}
      */
     private Integer sendStatus;
 

+ 80 - 30
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsQueryLogDO.java

@@ -1,15 +1,20 @@
 package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
 
+import cn.iocoder.dashboard.common.enums.UserTypeEnum;
+import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendFailureTypeEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsTemplateTypeEnum;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
-import java.io.Serializable;
 import java.util.Date;
+import java.util.Map;
 
 /**
- * 短信日志
+ * 短信发送日志
  *
  * @author zzf
  * @since 2021-01-25
@@ -18,73 +23,118 @@ import java.util.Date;
 @EqualsAndHashCode
 @Accessors(chain = true)
 @TableName(value = "sms_query_log", autoResultMap = true)
-public class SysSmsQueryLogDO implements Serializable {
+public class SysSmsQueryLogDO extends BaseDO {
 
     /**
      * 自增编号
      */
     private Long id;
 
+    // ========= 渠道相关字段 =========
+
     /**
-     * 第三方唯一标识
+     * 短信渠道编号
+     *
+     * 关联 {@link SysSmsChannelDO#getId()}
      */
-    private String apiId;
-
+    private Long channelId;
     /**
-     * 短信渠道编码(来自枚举类)
+     * 短信渠道编码
+     *
+     * 冗余 {@link SysSmsChannelDO#getCode()}
      */
     private String channelCode;
-
     /**
-     * 短信渠道id
+     * 实际渠道模板唯一标识
      */
-    private Long channelId;
+    private String apiTemplateId;
+
+    // ========= 模板相关字段 =========
 
     /**
-     * 模板id
+     * 短信模板编号
+     *
+     * 关联 {@link}
      */
     private String templateCode;
+    /**
+     * 短信类型
+     *
+     * 枚举 {@link SysSmsTemplateTypeEnum}
+     */
+    private Integer templateType;
+    /**
+     * 基于 {@link SysSmsTemplateDO#getContent()} 格式化后的内容
+     */
+    private String templateContent;
+    /**
+     * 基于 {@link SysSmsTemplateDO#getParams()} 输入后的内容
+     */
+    private Map<String, Object> templateParams;
+
+    // ========= 手机相关字段 =========
 
     /**
      * 手机号
      */
-    private String phone;
-
+    private String mobile;
     /**
-     * 内容
+     * 用户编号
+     */
+    private Integer userId;
+    /**
+     * 用户类型
+     *
+     * 枚举 {@link UserTypeEnum}
      */
-    private String content;
+    private Integer userType;
+
+    // ========= 发送相关字段 =========
 
     /**
      * 发送状态
      *
-     * @see cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum
+     * 枚举 {@link SysSmsSendStatusEnum}
      */
     private Integer sendStatus;
-
     /**
-     * 是否获取过结果[0否 1是]
+     * 发送失败的类型
+     *
+     * 枚举 {@link SysSmsSendFailureTypeEnum}
      */
-    private Integer gotResult;
-
+    private Integer sendFailureType;
     /**
-     * 备注
+     * 发送成功时间
      */
-    private String remark;
-
+    private Date sendTime;
     /**
-     * 创建人
+     * 短信 API 发送失败的类型
+     *
+     * 由于第三方的错误码可能是字符串,所以使用 String 类型
      */
-    private String createBy;
-
+    private String apiSendFailureType;
     /**
-     * 创建时间
+     * 短信 API 发送失败的提示
      */
-    private Date createTime;
+    private String apiSendFailureMsg;
+    /**
+     * 短信 API 发送返回的唯一请求 ID
+     *
+     * 用于和短信 API 进行定位于排错
+     */
+    private String apiRequestId;
+    /**
+     * 短信 API 发送返回的序号
+     *
+     * 用于和短信 API 平台的发送记录关联
+     */
+    private String apiSerialNo;
+
+    // ========= 接收相关字段 =========
 
     /**
-     * 发送时间
+     * 是否获取过结果[0否 1是]
      */
-    private Date sendTime;
+    private Integer gotResult;
 
 }

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsSendLogDO.java

@@ -1,6 +1,6 @@
 package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
 
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -54,7 +54,7 @@ public class SysSmsSendLogDO implements Serializable {
     /**
      * 发送状态
      *
-     * @see SmsSendStatusEnum
+     * @see SysSmsSendStatusEnum
      */
     private Integer sendStatus;
 

+ 25 - 27
src/main/java/cn/iocoder/dashboard/modules/system/dal/dataobject/sms/SysSmsTemplateDO.java

@@ -2,6 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.dataobject.sms;
 
 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsTemplateTypeEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
@@ -26,62 +27,59 @@ public class SysSmsTemplateDO extends BaseDO {
      */
     private Long id;
 
-    /**
-     * 短信渠道编码(来自枚举类)
-     */
-    private String channelCode;
+    // ========= 模板相关字段 =========
 
     /**
-     * 短信渠道id (对于前端来说就是绑定一个签名)
-     */
-    private Long channelId;
-
-    /**
-     * 消息类型 [0验证码 1短信通知 2推广短信 3国际/港澳台消息]
+     * 短信类型
+     *
+     * 枚举 {@link SysSmsTemplateTypeEnum}
      */
     private Integer type;
-
     /**
-     * 业务编码(来自数据字典, 用户自定义业务场景 一个场景可以有多个模板)
+     * 启用状态
+     *
+     * 枚举 {@link CommonStatusEnum}
      */
-    private String bizCode;
-
+    private Integer status;
     /**
-     * 模板编码
+     * 模板编码,保证唯一
      */
     private String code;
-
     /**
      * 名称
      */
     private String name;
-
-    /**
-     * 实际渠道模板唯一标识
-     */
-    private String apiTemplateId;
-
     /**
      * 内容
      */
     private String content;
-
     /**
      * 参数数组(自动根据内容生成)
      */
     @TableField(typeHandler = JacksonTypeHandler.class)
     private List<String> params;
-
     /**
      * 备注
      */
     private String remark;
 
+    // ========= 渠道相关字段 =========
+
     /**
-     * 启用状态
+     * 短信渠道编号
      *
-     * 枚举 {@link CommonStatusEnum}
+     * 关联 {@link SysSmsChannelDO#getId()}
      */
-    private Integer status;
+    private Long channelId;
+    /**
+     * 短信渠道编码
+     *
+     * 冗余 {@link SysSmsChannelDO#getCode()}
+     */
+    private String channelCode;
+    /**
+     * 短信 API 的模板编号
+     */
+    private String apiTemplateId;
 
 }

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/dal/mysql/sms/SysSmsQueryLogMapper.java

@@ -2,7 +2,7 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.sms;
 
 import cn.iocoder.dashboard.common.enums.DefaultBitFieldEnum;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsQueryLogDO;
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
@@ -17,7 +17,7 @@ public interface SysSmsQueryLogMapper extends BaseMapper<SysSmsQueryLogDO> {
      */
     default List<SysSmsQueryLogDO> selectNoResultQueryLogList() {
         return this.selectList(new LambdaQueryWrapper<SysSmsQueryLogDO>()
-                .eq(SysSmsQueryLogDO::getSendStatus, SmsSendStatusEnum.QUERY_SUCCESS)
+                .eq(SysSmsQueryLogDO::getSendStatus, SysSmsSendStatusEnum.QUERY_SUCCESS)
                 .eq(SysSmsQueryLogDO::getGotResult, DefaultBitFieldEnum.NO)
         );
     }

+ 1 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java

@@ -84,6 +84,7 @@ public interface SysErrorCodeConstants {
 
     // ========== 短信发送 1002011000 ==========
     ErrorCode SMS_SEND_MOBILE_NOT_EXISTS = new ErrorCode(1002011000, "手机号不存在");
+    ErrorCode SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS = new ErrorCode(1002011001, "模板参数({})缺失");
 
     ErrorCode SMS_CHANNEL_NOT_INIT = new ErrorCode(1003001001,
             "短信渠道没有初始化, 请调用SmsClientWrapper#initSmsClient()或SmsClientWrapper#addSmsClient");

+ 0 - 39
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SmsSendStatusEnum.java

@@ -1,39 +0,0 @@
-package cn.iocoder.dashboard.modules.system.enums.sms;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 短信发送状态
- *
- * @author zzf
- * @date 2021/2/1 13:39
- */
-@Getter
-@AllArgsConstructor
-public enum SmsSendStatusEnum {
-
-    //请求发送结果时失败
-    QUERY_SEND_FAIL(-3),
-
-    //短信发送失败
-    SEND_FAIL(-2),
-
-    //短信请求失败
-    QUERY_FAIL(-1),
-
-    //异步转发中
-    ASYNC(0),
-
-    //请求成功
-    QUERY_SUCCESS(1),
-
-    //短信成功
-    SEND_SUCCESS(2),
-
-    //等待回执
-    WAITING(3);
-
-    private final int status;
-
-}

+ 19 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendFailureTypeEnum.java

@@ -0,0 +1,19 @@
+package cn.iocoder.dashboard.modules.system.enums.sms;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 短信的发送失败类型的枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum SysSmsSendFailureTypeEnum {
+
+    ;
+
+    private final int type;
+
+}

+ 23 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsSendStatusEnum.java

@@ -0,0 +1,23 @@
+package cn.iocoder.dashboard.modules.system.enums.sms;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 短信的发送状态枚举
+ *
+ * @author zzf
+ * @date 2021/2/1 13:39
+ */
+@Getter
+@AllArgsConstructor
+public enum SysSmsSendStatusEnum {
+
+    INIT(0), // 初始化
+    SUCCESS(10), // 发送成功
+    FAILURE(20), // 发送失败
+    ;
+
+    private final int status;
+
+}

+ 25 - 0
src/main/java/cn/iocoder/dashboard/modules/system/enums/sms/SysSmsTemplateTypeEnum.java

@@ -0,0 +1,25 @@
+package cn.iocoder.dashboard.modules.system.enums.sms;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 短信的模板类型枚举
+ *
+ * @author 芋道源码
+ */
+@Getter
+@AllArgsConstructor
+public enum SysSmsTemplateTypeEnum {
+
+    VERIFICATION_CODE(1), // 验证码
+    NOTICE(2), // 通知
+    PROMOTION(3), // 营销
+    ;
+
+    /**
+     * 类型
+     */
+    private final int type;
+
+}

+ 2 - 0
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsService.java

@@ -19,6 +19,8 @@ public interface SysSmsService {
     void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType,
                       String templateCode, Map<String, Object> templateParams);
 
+    void doSendSms();
+
     /**
      * 处理短信发送回调函数
      *

+ 3 - 3
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsQueryLogServiceImpl.java

@@ -7,7 +7,7 @@ import cn.iocoder.dashboard.framework.sms.core.SmsResultDetail;
 import cn.iocoder.dashboard.framework.sms.core.property.SmsChannelProperty;
 import cn.iocoder.dashboard.modules.system.dal.mysql.dao.sms.SysSmsQueryLogMapper;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsQueryLogDO;
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsQueryLogService;
 import org.springframework.stereotype.Service;
 
@@ -36,7 +36,7 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService {
                 .setPhone(targetPhone)
                 .setContent(smsBody.getParams().toString());
 
-        smsLog.setSendStatus(SmsSendStatusEnum.ASYNC.getStatus());
+        smsLog.setSendStatus(SysSmsSendStatusEnum.ASYNC.getStatus());
         logMapper.insert(smsLog);
         smsBody.setSmsLogId(smsLog.getId());
     }
@@ -46,7 +46,7 @@ public class SysSmsQueryLogServiceImpl implements SysSmsQueryLogService {
         SysSmsQueryLogDO smsLog = new SysSmsQueryLogDO();
         smsLog.setId(logId);
         smsLog.setApiId(result.getApiId());
-        smsLog.setSendStatus(SmsSendStatusEnum.QUERY_FAIL.getStatus());
+        smsLog.setSendStatus(SysSmsSendStatusEnum.QUERY_FAIL.getStatus());
         smsLog.setRemark(result.getCode() + ": " + result.getMessage());
         logMapper.updateById(smsLog);
     }

+ 2 - 2
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsSendLogServiceImpl.java

@@ -6,7 +6,7 @@ import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsQueryLogDO;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.sms.SysSmsSendLogDO;
 import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsQueryLogMapper;
 import cn.iocoder.dashboard.modules.system.dal.mysql.sms.SysSmsSendLogMapper;
-import cn.iocoder.dashboard.modules.system.enums.sms.SmsSendStatusEnum;
+import cn.iocoder.dashboard.modules.system.enums.sms.SysSmsSendStatusEnum;
 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsChannelService;
 import cn.iocoder.dashboard.modules.system.service.sms.SysSmsSendLogService;
 import lombok.extern.slf4j.Slf4j;
@@ -88,7 +88,7 @@ public class SysSmsSendLogServiceImpl implements SysSmsSendLogService {
                 updateQueryLog.setSendStatus(SmsSendStatusEnum.QUERY_SEND_FAIL.getStatus());
                 smsQueryLogMapper.updateById(updateQueryLog);
             }*/
-            updateQueryLog.setSendStatus(SmsSendStatusEnum.SEND_SUCCESS.getStatus());
+            updateQueryLog.setSendStatus(SysSmsSendStatusEnum.SEND_SUCCESS.getStatus());
             updateQueryLog.setRemark(String.format("日志(id = %s)对应的客户端没有继承NeedQuerySendResultSmsClient, 不能获取短信结果。", queryLog.getId()));
             smsQueryLogMapper.updateById(updateQueryLog);
         });

+ 24 - 4
src/main/java/cn/iocoder/dashboard/modules/system/service/sms/impl/SysSmsServiceImpl.java

@@ -1,5 +1,7 @@
 package cn.iocoder.dashboard.modules.system.service.sms.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.dashboard.common.enums.UserTypeEnum;
 import cn.iocoder.dashboard.framework.sms.client.AbstractSmsClient;
@@ -21,6 +23,8 @@ import javax.servlet.ServletRequest;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
 
 import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
@@ -55,24 +59,40 @@ public class SysSmsServiceImpl implements SysSmsService {
     @Override
     public void sendSingleSms(String mobile, Long userId, Integer userType,
                               String templateCode, Map<String, Object> templateParams) {
-        // 校验短信模板是否存在
-        SysSmsTemplateDO template = this.checkSmsTemplateExists(templateCode);
+        // 校验短信模板是否合法
+        SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams);
         // 校验手机号码是否存在
         mobile = this.checkMobile(mobile, userId, userType);
+        //
     }
 
     @Override
     public void sendBatchSms(List<String> mobiles, List<Long> userIds, Integer userType,
                              String templateCode, Map<String, Object> templateParams) {
         // 校验短信模板是否存在
-        SysSmsTemplateDO template = this.checkSmsTemplateExists(templateCode);
+        SysSmsTemplateDO template = this.checkSmsTemplateValid(templateCode, templateParams);
     }
 
-    private SysSmsTemplateDO checkSmsTemplateExists(String templateCode) {
+    private SysSmsTemplateDO checkSmsTemplateValid(String templateCode, Map<String, Object> templateParams) {
+        // 短信模板不存在
         SysSmsTemplateDO template = smsTemplateService.getSmsTemplateByCode(templateCode);
         if (template == null) {
             throw exception(SMS_TEMPLATE_NOT_EXISTS);
         }
+        // 参数不够
+        if (CollUtil.isNotEmpty(template.getParams())) {
+            template.getParams().forEach(param -> {
+                if (!templateParams.containsKey(param)) {
+                    throw exception(SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS);
+                }
+            });
+        }
+        // 移除多余参数
+        if (CollUtil.isEmpty(template.getParams())) {
+            templateParams.clear();
+        } else {
+            templateParams.entrySet().removeIf(entry -> !template.getParams().contains(entry.getKey()));
+        }
         return template;
     }