Browse Source

Merge remote-tracking branch 'origin/master'

17358629955 2 years ago
parent
commit
d107f1169c
18 changed files with 662 additions and 137 deletions
  1. 4 0
      sckw-common/sckw-common-core/pom.xml
  2. 30 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/BusinessException.java
  3. 29 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/NotLoginException.java
  4. 113 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/global/GlobalExceptionHandler.java
  5. 4 20
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/config/RedissonConfig.java
  6. 0 50
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/configure/RedissonConfiguration.java
  7. 188 26
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/utils/RedissonUtils.java
  8. 9 29
      sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/enums/SmsCodeEnum.java
  9. 5 0
      sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/model/SckwSms.java
  10. 9 12
      sckw-modules/sckw-message/src/main/java/com/sckw/message/consumer/SckwSmsConsumer.java
  11. 9 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/MessageController.java
  12. 35 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/SmsController.java
  13. 16 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmSmsMapper.java
  14. 47 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmSms.java
  15. 30 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/SendSmsVerifyCoderReqVO.java
  16. 30 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmSmsService.java
  17. 46 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SckwSmsHandlerService.java
  18. 58 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SmsService.java

+ 4 - 0
sckw-common/sckw-common-core/pom.xml

@@ -98,6 +98,10 @@
             <artifactId>sckw-common-remote</artifactId>
             <version>1.0.0</version>
         </dependency>
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 30 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/BusinessException.java

@@ -0,0 +1,30 @@
+package com.sckw.core.exception;
+
+import lombok.Getter;
+
+/**
+ * @Author yzc
+ * @Description 自定义业务异常
+ * @createTime 2023年06月08日 10:05:00
+ */
+@Getter
+public class BusinessException extends RuntimeException {
+
+    /**
+     * 异常信息
+     **/
+    private String msg;
+    private Object[] param;
+
+    public BusinessException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+
+    public BusinessException(String msg, Object... param) {
+        super(msg);
+        this.msg = msg;
+        this.param = param;
+    }
+
+}

+ 29 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/NotLoginException.java

@@ -0,0 +1,29 @@
+package com.sckw.core.exception;
+
+import lombok.Getter;
+
+/**
+ * @Author yzc
+ * @Description 未登陆异常
+ * @createTime 2023年06月08日 10:05:00
+ */
+@Getter
+public class NotLoginException extends  RuntimeException {
+
+    /**
+     * 异常信息
+    **/
+    private String msg;
+    private Object[] param;
+
+    public NotLoginException(String msg) {
+        super(msg);
+        this.msg = msg;
+    }
+    public NotLoginException(String msg, Object... param){
+        super(msg);
+        this.msg = msg;
+        this.param=param;
+    }
+
+}

+ 113 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/global/GlobalExceptionHandler.java

@@ -0,0 +1,113 @@
+package com.sckw.core.global;
+
+import com.sckw.core.exception.BusinessException;
+import com.sckw.core.exception.NotLoginException;
+import com.sckw.core.web.constant.HttpStatus;
+import com.sckw.core.web.response.HttpResult;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @Author yzc
+ * @Description 统一异常处理
+ * @createTime 2023年06月08日 10:59:00
+ */
+@Slf4j
+@ControllerAdvice(basePackages = "com.sckw.*.controller")
+public class GlobalExceptionHandler {
+
+    /**
+     * exception处理
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(Exception.class)
+    public HttpResult defaultExceptionHandler(Exception ex) {
+        log.error("系统异常", ex);
+        return HttpResult.error(HttpStatus.GLOBAL_EXCEPTION_CODE, HttpStatus.GLOBAL_EXCEPTION_MESSAGE);
+    }
+
+    /**
+     * BusinessException处理
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(BusinessException.class)
+    public HttpResult businessExceptionHandler(BusinessException ex) {
+        log.info("业务异常,message={},param={}", ex.getMsg(), ex.getParam());
+        return HttpResult.error(HttpStatus.GLOBAL_EXCEPTION_CODE, ex.getMessage());
+    }
+
+    /**
+     * NotLoginException处理
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(NotLoginException.class)
+    public HttpResult notLoginException(NotLoginException ex) {
+        log.info("用户未登录, message={}, param={}", ex.getMsg(), ex.getParam());
+        return HttpResult.error(HttpStatus.UN_LOGIN_CODE, HttpStatus.UN_LOGIN_MESSAGE, ex.getMessage());
+    }
+
+
+    /**
+     * 注解校验异常处理
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseBody
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public HttpResult methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex) {
+        List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
+        StringBuilder sb = new StringBuilder();
+        if (!CollectionUtils.isEmpty(fieldErrors)) {
+            boolean first = true;
+            for (FieldError fieldError : fieldErrors) {
+                if (!first) {
+                    sb.append(",");
+                }
+                sb.append(fieldError.getDefaultMessage());
+                first = false;
+            }
+        }
+        String errMsg = sb.toString();
+        log.info("参数校验异常m:{}", errMsg);
+        return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE, errMsg);
+    }
+
+    @ResponseBody
+    @ExceptionHandler(ConstraintViolationException.class)
+    public HttpResult constraintViolationExceptionHandler(ConstraintViolationException ex) {
+        log.info("参数校验异常c:{}", ex.getMessage());
+        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
+        StringBuilder sb = new StringBuilder();
+        if (!CollectionUtils.isEmpty(constraintViolations)) {
+            boolean first = true;
+            for (ConstraintViolation<?> constraintViolation : constraintViolations) {
+                if (!first) {
+                    sb.append(",");
+                }
+                sb.append(constraintViolation.getMessage());
+                first = false;
+            }
+        }
+        return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE, sb.toString());
+    }
+}

+ 4 - 20
sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/config/RedissonConfig.java

@@ -6,7 +6,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import com.sckw.redis.config.serializer.FastJson2JsonRedisSerializer;
+import com.sckw.redis.utils.RedissonUtils;
+import org.redisson.api.RedissonClient;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -42,26 +43,9 @@ public class RedissonConfig {
         return redisTemplate;
     }
 
-    /**
-     * fastjson序列化方式的redisTemplate
-     *
-     * @param redisConnectionFactory
-     * @return
-     */
     @Bean
-    public RedisTemplate<String, Object> redisTemplateFastJson(RedisConnectionFactory redisConnectionFactory) {
-        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
-        redisTemplate.setConnectionFactory(redisConnectionFactory);
-        FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<>(Object.class);
-        // 设置值(value)的序列化采用FastJsonRedisSerializer。
-        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
-        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
-
-        // 设置键(key)的序列化采用StringRedisSerializer。
-        redisTemplate.setKeySerializer(new StringRedisSerializer());
-        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
-        redisTemplate.afterPropertiesSet();
-        return redisTemplate;
+    public RedissonUtils redissonUtils(RedissonClient redissonClient) {
+        return new RedissonUtils(redissonClient);
     }
 
     private Jackson2JsonRedisSerializer<Object> serializer() {

+ 0 - 50
sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/configure/RedissonConfiguration.java

@@ -1,50 +0,0 @@
-package com.sckw.redis.configure;
-
-import org.redisson.Redisson;
-import org.redisson.api.RedissonClient;
-import org.redisson.config.Config;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * @Author xxx
- * @DATE 2022/3/27 11:13
- */
-@Configuration
-public class RedissonConfiguration {
-
-    @Value("${spring.redis.host}")
-    private String address;
-
-    @Value("${spring.redis.port}")
-    private String port;
-
-    @Value("${spring.redis.password}")
-    private String password;
-
-    @Value("${spring.redis.database}")
-    private String database;
-
-    @Value("${spring.redis.timeout}")
-    private String timeout;
-
-    @Bean
-    public RedissonClient redisson() {
-        Config config = new Config();
-        config.useSingleServer()
-                .setAddress(address())
-                .setPassword(password)
-                .setDatabase(Integer.parseInt(database))
-                .setConnectTimeout(Integer.parseInt(timeout));
-        return Redisson.create(config);
-    }
-
-    /**
-     * 生成address
-     * @return
-     */
-    private String address() {
-        return "redis://" + address + ":" + port;
-    }
-}

+ 188 - 26
sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/utils/RedissonUtils.java

@@ -1,29 +1,42 @@
 package com.sckw.redis.utils;
 
-import org.redisson.api.RBucket;
-import org.redisson.api.RedissonClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.*;
+import org.redisson.client.codec.StringCodec;
+
+import java.time.Duration;
 import java.util.concurrent.TimeUnit;
 
-@Component
+@Slf4j
 public class RedissonUtils {
 
-    @Autowired
-    RedissonClient redissonClient;
+    private RedissonClient redissonClient;
+
+    private static RedissonUtils redissonUtils;
+
+    public RedissonUtils(RedissonClient redissonClient) {
+        redissonUtils = this;
+        this.redissonClient = redissonClient;
+    }
+
+    /**
+     * 默认缓存时间
+     */
+    private static final Long DEFAULT_EXPIRED = 5 * 60L;
 
     /**
      * 添加缓存
-     * @param key key
+     *
+     * @param key   key
      * @param value value
      */
-    public void add(String key, String value) {
+    public static void add(String key, String value) {
         //根据key获取bucket桶对象
-        RBucket<Object> bucket = redissonClient.getBucket(key);
+        RBucket<Object> bucket = redissonUtils.redissonClient.getBucket(key);
         //判读是否存在,并打印日志信息
         if (!bucket.isExists()) {
             //log.info("");
-        }else {
+        } else {
             //log.info("update data");
         }
         //添加缓存,若已存在,则替换,设置缓存超时时间
@@ -32,33 +45,182 @@ public class RedissonUtils {
 
 
     /**
-     * 在缓存中获取信息
+     * 删除缓存信息
+     *
      * @param key key
-     * @return 信息结果
      */
-    public Object get(String key) {
+    public static void delete(String key) {
         //根据key获取bucket桶对象
-        RBucket<Object> bucket = redissonClient.getBucket(key);
+        RBucket<Object> bucket = redissonUtils.redissonClient.getBucket(key);
         //判读是否存在,并打印日志信息
         if (!bucket.isExists()) {
             //log.info("error");
         }
-        //log.info("cache is {}", bucket.get());
+        bucket.delete();
+    }
+
+    /**
+     * 判断缓存是否存在
+     *
+     * @param key
+     * @return
+     */
+    public static boolean exists(String key) {
+        return redissonUtils.redissonClient.getBucket(key).isExists();
+    }
+
+
+    /**
+     * 读取缓存
+     *
+     * @param key 缓存key
+     * @param <T>
+     * @return 缓存返回值
+     */
+    public static <T> T get(String key) {
+        RBucket<T> bucket = redissonUtils.redissonClient.getBucket(key);
         return bucket.get();
     }
 
     /**
-     * 删除缓存信息
-     * @param key key
+     * 以string的方式读取缓存
+     *
+     * @param key 缓存key
+     * @return 缓存返回值
      */
-    public void delete(String key) {
-        //根据key获取bucket桶对象
-        RBucket<Object> bucket = redissonClient.getBucket(key);
-        //判读是否存在,并打印日志信息
-        if (!bucket.isExists()) {
-            //log.info("error");
-        }
-        bucket.delete();
+    public static String getString(String key) {
+        RBucket<String> bucket = redissonUtils.redissonClient.getBucket(key, StringCodec.INSTANCE);
+        return bucket.get();
+    }
+
+    /**
+     * 设置缓存(注:redisson会自动选择序列化反序列化方式)
+     *
+     * @param key   缓存key
+     * @param value 缓存值
+     * @param <T>
+     */
+    public static <T> void put(String key, T value) {
+        log.debug("添加缓存【{}】 【{}】开始", key, value);
+        RBucket<T> bucket = redissonUtils.redissonClient.getBucket(key);
+        bucket.set(value, DEFAULT_EXPIRED, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 以string的方式设置缓存
+     *
+     * @param key
+     * @param value
+     */
+    public static void putString(String key, String value, long expired) {
+        log.debug("添加缓存【{}】 【{}】开始", key, value);
+        RBucket<String> bucket = redissonUtils.redissonClient.getBucket(key, StringCodec.INSTANCE);
+        bucket.set(value, expired <= 0 ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 如果不存在则写入缓存(string方式,不带有redisson的格式信息)
+     *
+     * @param key     缓存key
+     * @param value   缓存值
+     * @param expired 缓存过期时间
+     */
+    public boolean putStringIfAbsent(String key, String value, long expired) {
+        log.debug("如果不存在则写入缓存【{}】 【{}】 【{}】开始", key, value, expired);
+        RBucket<String> bucket = redissonUtils.redissonClient.getBucket(key, StringCodec.INSTANCE);
+        return bucket.setIfAbsent(value, expired <= 0 ? Duration.ofSeconds(DEFAULT_EXPIRED) : Duration.ofSeconds(expired));
+    }
+
+    /**
+     * 如果不存在则写入缓存(string方式,不带有redisson的格式信息)(不带过期时间,永久保存)
+     *
+     * @param key   缓存key
+     * @param value 缓存值
+     */
+    public boolean putStringIfAbsent(String key, String value) {
+        log.debug("如果不存在则写入永久缓存【{}】 【{}】开始", key, value);
+        RBucket<String> bucket = redissonUtils.redissonClient.getBucket(key, StringCodec.INSTANCE);
+        return bucket.setIfAbsent(value);
+    }
+
+    /**
+     * 设置缓存
+     *
+     * @param key     缓存key
+     * @param value   缓存值
+     * @param expired 缓存过期时间
+     * @param <T>     类型
+     */
+    public static <T> void put(String key, T value, long expired) {
+        log.debug("如果不存在则写入缓存【{}】 【{}】 【{}】开始", key, value, expired);
+        RBucket<T> bucket = redissonUtils.redissonClient.getBucket(key);
+        bucket.set(value, expired <= 0 ? DEFAULT_EXPIRED : expired, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 移除缓存
+     *
+     * @param key
+     */
+    public static void remove(String key) {
+        log.debug("移除缓存【{}】开始", key);
+        redissonUtils.redissonClient.getBucket(key).delete();
+    }
+
+    /**
+     * 暴露redisson的RList对象
+     *
+     * @param key
+     * @param <T>
+     * @return
+     */
+    public static <T> RList<T> getRedisList(String key) {
+        return redissonUtils.redissonClient.getList(key);
+    }
+
+    /**
+     * 暴露redisson的RMapCache对象
+     *
+     * @param key
+     * @param <K>
+     * @param <V>
+     * @return
+     */
+    public static <K, V> RMapCache<K, V> getRedisMap(String key) {
+        return redissonUtils.redissonClient.getMapCache(key);
+    }
+
+    /**
+     * 暴露redisson的RSET对象
+     *
+     * @param key
+     * @param <T>
+     * @return
+     */
+    public static <T> RSet<T> getRedisSet(String key) {
+        return redissonUtils.redissonClient.getSet(key);
+    }
+
+
+    /**
+     * 暴露redisson的RScoredSortedSet对象
+     *
+     * @param key
+     * @param <T>
+     * @return
+     */
+    public static <T> RScoredSortedSet<T> getRedisScoredSortedSet(String key) {
+        return redissonUtils.redissonClient.getScoredSortedSet(key);
+    }
+
+    /**
+     * 暴露redisson的Lock对象
+     *
+     * @param key
+     * @return
+     */
+    public static RLock getRedisLock(String key) {
+        return redissonUtils.redissonClient.getLock(key);
     }
 
 }

+ 9 - 29
sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/enums/SmsCodeEnum.java

@@ -1,7 +1,15 @@
 package com.sckw.stream.enums;
 
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
 public enum SmsCodeEnum {
-    VERIFICATION_CODE("SMS_262585113", "验证码", "您的验证码为:${code},该验证码为平台重要凭证,请勿泄露于他人!");
+
+    VERIFICATION_CODE("VERIFICATION_CODE", "SMS_262585113", "验证码", "您的验证码为:${code},该验证码为平台重要凭证,请勿泄露于他人!");
+
+    private String type;
 
     private String name;
 
@@ -9,19 +17,6 @@ public enum SmsCodeEnum {
 
     private String value;
 
-    /**
-     * @description 构造方法
-     * @author zk
-     * @date 2020/6/08 11:28
-     * @param value 键 标题 类型 name 值
-     * @return
-     **/
-    private SmsCodeEnum(String name, String title, String value){
-        this.name = name;
-        this.value = value;
-        this.value = value;
-    }
-
     public static String getNameByValue(String value) {
         for (SmsCodeEnum entityEnum : SmsCodeEnum.values()) {
             if (entityEnum.getValue().equals(value)) {
@@ -31,19 +26,4 @@ public enum SmsCodeEnum {
         return null;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public void setValue(String value) {
-        this.value = value;
-    }
 }

+ 5 - 0
sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/model/SckwSms.java

@@ -40,5 +40,10 @@ public class SckwSms {
      * 签名
      */
     private String signName;
+
+    /**
+     * 有效时间
+     */
+    private Long effectiveTime;
 }
 

+ 9 - 12
sckw-modules/sckw-message/src/main/java/com/sckw/message/consumer/SckwSmsConsumer.java

@@ -1,31 +1,28 @@
 package com.sckw.message.consumer;
 
 import com.alibaba.fastjson2.JSON;
+import com.sckw.message.service.SckwSmsHandlerService;
 import com.sckw.stream.model.SckwSms;
 import com.sckw.stream.utils.SmsUtil;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
 
 import java.util.function.Consumer;
 
-@Configuration
+
+@Component
 @Slf4j
+@RequiredArgsConstructor
 public class SckwSmsConsumer {
 
+    private final SckwSmsHandlerService sckwSmsHandlerService;
+
     @Bean
     public Consumer<SckwSms> sckwSms() {
         return sckwSms -> {
-            try {
-                /**发送短信**/
-                SmsUtil.sendSms(sckwSms.getTelephone(), sckwSms.getSignName(), sckwSms.getTemplateCode().getName(), JSON.toJSONString(sckwSms.getParams()));
-                /**数据入库**/
-
-                System.out.println("短信发送成功");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            System.out.println("sckwSms: " + sckwSms);
+            sckwSmsHandlerService.handler(sckwSms);
         };
     }
 

+ 9 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/MessageController.java

@@ -0,0 +1,9 @@
+package com.sckw.message.controller;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 10:58
+ * @description:
+ */
+public class MessageController {
+}

+ 35 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/SmsController.java

@@ -0,0 +1,35 @@
+package com.sckw.message.controller;
+
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.message.model.vo.req.SendSmsVerifyCoderReqVO;
+import com.sckw.message.service.SmsService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 10:58
+ * @description: 短信相關接口
+ */
+
+@RestController
+@RequestMapping(value = "/kwmSms")
+@RequiredArgsConstructor
+public class SmsController {
+
+    private final SmsService smsService;
+
+    @PostMapping(value = "/sendVerifyCode", produces = MediaType.APPLICATION_JSON_VALUE)
+    public HttpResult sendVerifyCode(@Valid @RequestBody SendSmsVerifyCoderReqVO param) {
+        smsService.sendVerifyCode(param);
+        return HttpResult.ok();
+    }
+
+    @GetMapping(value = "/getVerifyCode")
+    public HttpResult getVerifyCode(@RequestParam String phone) {
+        return HttpResult.ok("获取验证码成功", smsService.getVerifyCode(phone));
+    }
+
+}

+ 16 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmSmsMapper.java

@@ -0,0 +1,16 @@
+package com.sckw.message.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.message.model.KwmSms;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 15:49
+ * @description: 短信发送记录mapper
+ */
+
+@Mapper
+public interface KwmSmsMapper extends BaseMapper<KwmSms> {
+
+}

+ 47 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmSms.java

@@ -0,0 +1,47 @@
+package com.sckw.message.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sckw.core.model.base.BaseModel;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 15:44
+ * @description: 短信发送记录
+ */
+@Getter
+@Setter
+@ToString
+@Builder
+@TableName("kwm_sms")
+public class KwmSms extends BaseModel {
+    /**
+     * 短信类型
+     */
+    private String type;
+
+    /**
+     * 短信模板code
+     */
+    private String code;
+
+    /**
+     * 手机号
+     */
+    private String telephone;
+
+    /**
+     * 发送内容
+     */
+    private String content;
+
+    /**
+     * 参数
+     */
+    private String params;
+
+
+}

+ 30 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/SendSmsVerifyCoderReqVO.java

@@ -0,0 +1,30 @@
+package com.sckw.message.model.vo.req;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Pattern;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 11:30
+ * @description: 发送短信验证码请求参数
+ */
+
+@Getter
+@Setter
+@ToString
+@Accessors(chain = true)
+public class SendSmsVerifyCoderReqVO {
+
+    @NotBlank(message = "手机号不能为空!")
+    @Pattern(regexp = "^1[0-9]{10}$", message = "非法的手机号")
+    private String phone;
+
+
+    @NotNull(message = "有效时间不能为空!")
+    private Integer effectiveTime;
+}

+ 30 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmSmsService.java

@@ -0,0 +1,30 @@
+package com.sckw.message.service;
+
+import com.sckw.message.dao.KwmSmsMapper;
+import com.sckw.message.model.KwmSms;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 15:48
+ * @description:
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class KwmSmsService {
+
+    private final KwmSmsMapper kwmSmsMapper;
+
+    /**
+     * 添加
+     *
+     * @param kwmSms
+     */
+    public void add(KwmSms kwmSms) {
+        kwmSmsMapper.insert(kwmSms);
+    }
+
+}

+ 46 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SckwSmsHandlerService.java

@@ -0,0 +1,46 @@
+package com.sckw.message.service;
+
+import com.alibaba.fastjson2.JSON;
+import com.sckw.message.model.KwmSms;
+import com.sckw.redis.utils.RedissonUtils;
+import com.sckw.stream.enums.SmsCodeEnum;
+import com.sckw.stream.model.SckwSms;
+import com.sckw.stream.utils.SmsUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 15:54
+ * @description: 短信处理service
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class SckwSmsHandlerService {
+
+    private final KwmSmsService kwmSmsService;
+
+    private static final String MESSAGE_SMS_VERIFY_CODE_KEY = "sckw:message:sms:verifyCode:%s";
+
+    public void handler(SckwSms sckwSms) {
+        String key = getMessageSmsVerifyCodeKey(sckwSms.getTelephone());
+        if (RedissonUtils.exists(key)){
+            return;
+        }
+        //发送短信
+        RedissonUtils.putString(key, String.valueOf(sckwSms.getParams().get("code")), sckwSms.getEffectiveTime());
+        SmsUtil.sendSms(sckwSms.getTelephone(), sckwSms.getSignName(), sckwSms.getTemplateCode().getName(), JSON.toJSONString(sckwSms.getParams()));
+        //数据入库
+        SmsCodeEnum smsCodeEnum = sckwSms.getTemplateCode();
+        KwmSms kwmSms = KwmSms.builder().type(smsCodeEnum.getType()).code(smsCodeEnum.getName())
+                .telephone(sckwSms.getTelephone()).content(smsCodeEnum.getValue())
+                .params(JSON.toJSONString(sckwSms.getParams())).build();
+        kwmSmsService.add(kwmSms);
+    }
+
+    private String getMessageSmsVerifyCodeKey(String phone) {
+        return String.format(MESSAGE_SMS_VERIFY_CODE_KEY, phone);
+    }
+}

+ 58 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SmsService.java

@@ -0,0 +1,58 @@
+package com.sckw.message.service;
+
+import com.alibaba.fastjson2.JSON;
+import com.sckw.core.exception.BusinessException;
+import com.sckw.core.utils.NumberUtils;
+import com.sckw.message.model.vo.req.SendSmsVerifyCoderReqVO;
+import com.sckw.redis.utils.RedissonUtils;
+import com.sckw.stream.enums.SmsCodeEnum;
+import com.sckw.stream.model.SckwSms;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.stream.function.StreamBridge;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 11:08
+ * @description:
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class SmsService {
+
+    private final StreamBridge streamBridge;
+
+    private static final String MESSAGE_SMS_VERIFY_CODE_KEY = "sckw:message:sms:verifyCode:%s";
+
+    public void sendVerifyCode(SendSmsVerifyCoderReqVO param) {
+        String phone = param.getPhone();
+        // 防重攻击
+        String messageSmsVerifyCodeKey = getMessageSmsVerifyCodeKey(phone);
+        if (Boolean.TRUE.equals(RedissonUtils.exists(messageSmsVerifyCodeKey))) {
+            throw new BusinessException("请勿频繁获取短信验证码");
+        }
+        SckwSms sckwSms = new SckwSms();
+        sckwSms.setTelephone(param.getPhone());
+        sckwSms.setSignName("矿拉拉");
+        sckwSms.setTemplateCode(SmsCodeEnum.VERIFICATION_CODE);
+        Map<String, Object> params = new HashMap<>();
+        params.put("code", NumberUtils.createRandomVcode());
+        sckwSms.setParams(params);
+        sckwSms.setEffectiveTime(Long.valueOf(param.getEffectiveTime()));
+        streamBridge.send("sckw-sms", JSON.toJSONString(sckwSms));
+    }
+
+    public String getVerifyCode(String phone) {
+        String messageSmsVerifyCodeKey = getMessageSmsVerifyCodeKey(phone);
+        return RedissonUtils.getString(messageSmsVerifyCodeKey);
+    }
+
+    private String getMessageSmsVerifyCodeKey(String phone) {
+        return String.format(MESSAGE_SMS_VERIFY_CODE_KEY, phone);
+    }
+}