ソースを参照

Merge remote-tracking branch 'origin/master' into dev_czh

# Conflicts:
#	sckw-common/sckw-common-core/pom.xml
#	sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/configure/RedissonConfiguration.java
PC 2 年 前
コミット
3763174e7b
48 ファイル変更2282 行追加361 行削除
  1. 30 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/BusinessException.java
  2. 29 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/exception/NotLoginException.java
  3. 113 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/global/GlobalExceptionHandler.java
  4. 171 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/NumberUtils.java
  5. 59 0
      sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/RegularUtils.java
  6. 1 0
      sckw-common/sckw-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  7. 3 10
      sckw-common/sckw-common-elasticsearch/pom.xml
  8. 339 198
      sckw-common/sckw-common-elasticsearch/src/main/java/com/sckw/elasticsearch/service/es/EsUtils.java
  9. 16 10
      sckw-common/sckw-common-elasticsearch/src/main/java/com/sckw/elasticsearch/service/es/autoconfigure/EsAutoConfiguration.java
  10. 4 20
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/config/RedissonConfig.java
  11. 7 9
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/configure/RedissonConfiguration.java
  12. 197 25
      sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/utils/RedissonUtils.java
  13. 9 29
      sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/enums/SmsCodeEnum.java
  14. 1 1
      sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/model/SckwMessage.java
  15. 5 0
      sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/model/SckwSms.java
  16. 44 28
      sckw-modules/sckw-example/src/main/java/com/sckw/example/controller/EsController.java
  17. 22 0
      sckw-modules/sckw-example/src/main/java/com/sckw/example/model/Product.java
  18. 2 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/MessageApplication.java
  19. 14 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/constant/RedisConstant.java
  20. 17 2
      sckw-modules/sckw-message/src/main/java/com/sckw/message/consumer/SckwMessageConsumer.java
  21. 13 9
      sckw-modules/sckw-message/src/main/java/com/sckw/message/consumer/SckwSmsConsumer.java
  22. 68 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/MessageController.java
  23. 35 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/controller/SmsController.java
  24. 14 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmMessageMapper.java
  25. 15 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmMessageUserMapper.java
  26. 16 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmSmsMapper.java
  27. 57 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmMessage.java
  28. 32 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmMessageUser.java
  29. 47 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmSms.java
  30. 36 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/DeleteMessagesReqVO.java
  31. 30 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/FindMessagesReqVO.java
  32. 38 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/ReadMessagesReqVO.java
  33. 28 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/SendSmsVerifyCoderReqVO.java
  34. 90 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmMessageService.java
  35. 83 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmMessageUserService.java
  36. 30 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmSmsService.java
  37. 106 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/MessageService.java
  38. 63 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SckwMessageHandlerService.java
  39. 48 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SckwSmsHandlerService.java
  40. 57 0
      sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SmsService.java
  41. 3 3
      sckw-modules/sckw-message/src/main/resources/bootstrap-dev.yml
  42. 31 6
      sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/SysDictController.java
  43. 36 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/SysDictTypeDao.java
  44. 5 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/model/SysDict.java
  45. 24 0
      sckw-modules/sckw-system/src/main/java/com/sckw/system/model/SysDictType.java
  46. 46 10
      sckw-modules/sckw-system/src/main/java/com/sckw/system/service/SysDictService.java
  47. 11 1
      sckw-modules/sckw-system/src/main/resources/mapper/SysDictDao.xml
  48. 137 0
      sckw-modules/sckw-system/src/main/resources/mapper/SysDictTypeDao.xml

+ 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
+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());
+    }
+}

+ 171 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/NumberUtils.java

@@ -0,0 +1,171 @@
+package com.sckw.core.utils;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+/**
+ * @author zk
+ * @description 数值处理类
+ * @date 2020/06/06 09:00:32
+ */
+public class NumberUtils {
+    private static final int SIX = 6;
+    public NumberUtils() {
+    }
+
+    public static boolean parseBoolean(Object obj) {
+        if (obj == null) {
+            return false;
+        } else if (obj instanceof Boolean) {
+            return (Boolean)obj;
+        } else {
+            return obj instanceof String ? "true".equalsIgnoreCase(((String)obj).trim()) : false;
+        }
+    }
+
+    public static int parseInt(Object obj) {
+        return parseInt(obj, 0);
+    }
+
+    public static int parseInt(Object obj, int defaultValue) {
+        if (obj == null) {
+            return defaultValue;
+        } else if (obj instanceof String) {
+            try {
+                String str = ((String)obj).trim();
+                return str.length() == 0 ? defaultValue : Integer.parseInt(str);
+            } catch (NumberFormatException var3) {
+                return defaultValue;
+            }
+        } else {
+            return obj instanceof Number ? ((Number)obj).intValue() : defaultValue;
+        }
+    }
+
+    public static long parseLong(Object obj) {
+        return parseLong(obj, 0L);
+    }
+
+    public static long parseLong(Object obj, long defaultValue) {
+        if (obj == null) {
+            return defaultValue;
+        } else if (obj instanceof String) {
+            try {
+                return Long.parseLong(((String)obj).trim());
+            } catch (NumberFormatException var4) {
+                return defaultValue;
+            }
+        } else {
+            return obj instanceof Number ? ((Number)obj).longValue() : defaultValue;
+        }
+    }
+
+    public static float parseFloat(Object obj) {
+        return parseFloat(obj, 0.0F);
+    }
+
+    public static float parseFloat(Object obj, float defaultValue) {
+        if (obj == null) {
+            return defaultValue;
+        } else if (obj instanceof String) {
+            try {
+                return Float.parseFloat(((String)obj).trim());
+            } catch (NumberFormatException var3) {
+                return defaultValue;
+            }
+        } else {
+            return obj instanceof Number ? ((Number)obj).floatValue() : defaultValue;
+        }
+    }
+
+    public static double parseDouble(Object str) {
+        return parseDouble(str, 0.0D);
+    }
+
+    public static double parseDouble(Object obj, double defaultValue) {
+        if (obj == null) {
+            return defaultValue;
+        } else if (obj instanceof String) {
+            try {
+                return Double.parseDouble(((String)obj).trim());
+            } catch (NumberFormatException var4) {
+                return defaultValue;
+            }
+        } else {
+            return obj instanceof Number ? ((Number)obj).doubleValue() : defaultValue;
+        }
+    }
+
+    public static BigDecimal parseBigDecimal(Object obj) {
+        return parseBigDecimal(obj, new BigDecimal(0));
+    }
+
+    public static BigDecimal parseBigDecimal(Object obj, BigDecimal defaultValue) {
+        if (obj == null) {
+            return defaultValue;
+        } else if (obj instanceof String) {
+            try {
+                String s = (String)obj;
+                s = s.trim();
+                if (s.length() == 0) {
+                    s = "0";
+                }
+
+                return new BigDecimal(s);
+            } catch (NumberFormatException var3) {
+                return defaultValue;
+            }
+        } else if (obj instanceof BigDecimal) {
+            return (BigDecimal)obj;
+        } else if (obj instanceof Integer) {
+            return new BigDecimal((Integer)obj);
+        } else if (obj instanceof Long) {
+            return new BigDecimal((Long)obj);
+        } else if (obj instanceof Float) {
+            return new BigDecimal((double)(Float)obj);
+        } else if (obj instanceof Double) {
+            return new BigDecimal((Double)obj);
+        } else {
+            return obj instanceof Number ? new BigDecimal(((Number)obj).doubleValue()) : defaultValue;
+        }
+    }
+
+    public static String formatNumberValue(Object obj) {
+        return formatNumber(obj, "###0.00");
+    }
+
+    public static String formatNumberStr(Object obj) {
+        return formatNumber(obj, "#,##0.00");
+    }
+
+    public static String formatNumberEmpty(Object obj) {
+        if (obj == null) {
+            obj = new BigDecimal(0);
+        }
+
+        return ((Number)obj).intValue() == 0 ? "" : formatNumberStr(obj);
+    }
+
+    public static String formatNumber(Object obj, String pattern) {
+        if (obj == null) {
+            obj = new BigDecimal(0);
+        }
+
+        NumberFormat nf = new DecimalFormat(pattern);
+        return nf.format(obj);
+    }
+
+    /**
+     * 生成六位随机数
+     * @return
+     */
+    public static String createRandomVcode() {
+        //验证码
+        StringBuilder vcode = new StringBuilder();
+        for (int i = 0; i < SIX; i++) {
+            vcode.append((int) (Math.random() * 9));
+        }
+        return vcode.toString();
+    }
+}

+ 59 - 0
sckw-common/sckw-common-core/src/main/java/com/sckw/core/utils/RegularUtils.java

@@ -0,0 +1,59 @@
+package com.sckw.core.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author zk
+ * @description 正则表达式校验
+ * @date 2020/05/09 14:37:50
+ */
+public class RegularUtils {
+    /**
+     * 手机号
+     */
+    public static final String PHONE_REG = "^1[3456789]\\d{9}$";
+
+    /**
+     * 浮点型(不包括0)保留两位小数
+     */
+    public static final String DECIMAL_REG = "^[+]?(([1-9]\\d*[.]?)|(0.))(\\d{1,2})?$";
+
+    /**
+     * 非负浮点型(包括0)
+     */
+    public static final String DECIMAL_REG1 = "^\\d+(\\.\\d+)?$";
+    /**
+     *  数字和字母
+     */
+    public static final String NUMBER_AND_LATTER = "[0-9A-Za-z]{18}";
+
+    /**
+     * 正整数和0
+     */
+    public static final String NUMBER = "^[1-9]\\d*|0$";
+
+    /**
+     * 金额
+     */
+    public static final String DECIMAL_REG2 = "^(-?\\d+)(\\.\\d+)?$";
+
+    /**
+     * ${xxxxx}
+     */
+    public static final String DOLLAR_BIG_BRACKETS = "(\\$\\{)([\\w]+)(\\})";
+
+    /**
+     * @description 校验
+     * @author zk
+     * @date 2020/5/9 14:38
+     * @param
+     * @return
+     **/
+    public static boolean matchs(String regular, String str){
+        Pattern p = Pattern.compile(regular);
+        Matcher m = p.matcher(str);
+        boolean isMatch = m.matches();
+        return isMatch;
+    }
+}

+ 1 - 0
sckw-common/sckw-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.sckw.core.aspect.DaoAspect

+ 3 - 10
sckw-common/sckw-common-elasticsearch/pom.xml

@@ -18,14 +18,12 @@
         <maven.compiler.target>17</maven.compiler.target>
         <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <elasticsearch.version>7.9.3</elasticsearch.version>
+        <elasticsearch.version>8.5.3</elasticsearch.version>
     </properties>
-
-
     <dependencies>
         <dependency>
-            <groupId>org.elasticsearch.client</groupId>
-            <artifactId>elasticsearch-rest-high-level-client</artifactId>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
             <version>${elasticsearch.version}</version>
         </dependency>
         <dependency>
@@ -33,11 +31,6 @@
             <artifactId>elasticsearch-rest-client</artifactId>
             <version>${elasticsearch.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.elasticsearch</groupId>
-            <artifactId>elasticsearch</artifactId>
-            <version>${elasticsearch.version}</version>
-        </dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>

+ 339 - 198
sckw-common/sckw-common-elasticsearch/src/main/java/com/sckw/elasticsearch/service/es/EsUtils.java

@@ -1,40 +1,29 @@
 package com.sckw.elasticsearch.service.es;
 
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.ElasticsearchException;
+import co.elastic.clients.elasticsearch._types.FieldValue;
+import co.elastic.clients.elasticsearch._types.SortOrder;
+import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
+import co.elastic.clients.elasticsearch._types.aggregations.TermsAggregation;
+import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
+import co.elastic.clients.elasticsearch._types.query_dsl.Query;
+import co.elastic.clients.elasticsearch.core.*;
+import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
+import co.elastic.clients.elasticsearch.core.search.Hit;
+import co.elastic.clients.elasticsearch.indices.IndexSettings;
+import co.elastic.clients.json.JsonData;
+import co.elastic.clients.util.ObjectBuilder;
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
 import lombok.extern.slf4j.Slf4j;
-import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
-import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
-import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
-import org.elasticsearch.action.bulk.BulkRequest;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.search.ClearScrollRequest;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.action.support.IndicesOptions;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.client.core.CountRequest;
-import org.elasticsearch.client.core.CountResponse;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.elasticsearch.index.query.TermQueryBuilder;
-import org.elasticsearch.index.reindex.BulkByScrollResponse;
-import org.elasticsearch.index.reindex.DeleteByQueryRequest;
-import org.elasticsearch.index.reindex.UpdateByQueryRequest;
-import org.elasticsearch.script.Script;
-import org.elasticsearch.search.SearchHits;
-import org.elasticsearch.search.aggregations.Aggregations;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.springframework.util.CollectionUtils;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.Function;
 
 /**
  * @author yuzhongchuan
@@ -44,310 +33,462 @@ import java.util.Objects;
 @Slf4j
 public class EsUtils {
 
-    private RestHighLevelClient client;
+    private ElasticsearchClient client;
 
     private static EsUtils esUtils;
 
-    public EsUtils(RestHighLevelClient client) {
+    public EsUtils(ElasticsearchClient client) {
         esUtils = this;
         this.client = client;
     }
 
     /**
-     * 创建索引
+     * @param name
+     * @return void
+     * @desc: 创建索引
+     * @author: yzc
+     * @date: 2023-06-12 11:46
+     */
+    public static void addIndex(String name) {
+        try {
+            if (indexExists(name)) {
+                log.error(" idxName={} 已经存在", name);
+                return;
+            }
+            esUtils.client.indices().create(c -> c.index(name));
+        } catch (IOException e) {
+            log.error("ES addIndex异常", e);
+        }
+    }
+
+    /**
+     * @param name
+     * @return boolean
+     * @desc: 索引是否存在
+     * @author: yzc
+     * @date: 2023-06-12 11:46
+     */
+    public static boolean indexExists(String name) throws IOException {
+        return esUtils.client.indices().exists(b -> b.index(name)).value();
+    }
+
+    /**
+     * @param name
+     * @return void
+     * @desc: 删除索引
+     * @author: yzc
+     * @date: 2023-06-12 11:47
+     */
+    public static void delIndex(String name) {
+        try {
+            if (!indexExists(name)) {
+                log.error(" idxName={} 不存在", name);
+                return;
+            }
+            esUtils.client.indices().delete(c -> c.index(name));
+        } catch (IOException e) {
+            log.error("ES delIndex异常", e);
+        }
+    }
+
+    /**
+     * @param idxName, settingFn, mappingFn
+     * @return void
+     * @desc: 带mapping、setting创建索引
+     * @author: yzc
+     * @date: 2023-06-12 11:47
+     */
+    public static void createIndex(String idxName,
+                                   Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn,
+                                   Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn) {
+        try {
+            if (indexExists(idxName)) {
+                log.error(" idxName={} 已经存在", idxName);
+                return;
+            }
+            esUtils.client.indices().create(c -> c
+                    .index(idxName)
+                    .settings(settingFn)
+                    .mappings(mappingFn));
+        } catch (IOException e) {
+            log.error("ES createIndex异常", e);
+        }
+    }
+
+    /**
+     * 添加文档信息
      *
      * @param idxName
-     * @param idxSql
+     * @param t
+     * @param <T>
      */
-    public static void createIndex(String idxName, String idxSql) {
-        if (!indexExist(idxName)) {
-            log.error(" idxName={} 已经存在,idxSql={}", idxName, idxSql);
+    public static <T> void add(String idxName, T t) {
+        if (Objects.isNull(idxName) || t == null) {
             return;
         }
-        log.info(" idxName={} 创建索引,idxSql={}", idxName, idxSql);
-        CreateIndexRequest request = new CreateIndexRequest(idxName);
-        buildSetting(request);
-        request.mapping("_doc", idxSql, XContentType.JSON);
         try {
-            esUtils.client.indices().create(request, RequestOptions.DEFAULT);
+            esUtils.client.index(s ->
+                    s.index(idxName).document(t));
         } catch (IOException e) {
-            log.error("ES createIndex异常", e);
+            log.error("es插入单条新数据异常:", e);
         }
     }
 
     /**
-     * 删除索引
+     * 添加文档信息 指定id
      *
-     * @param idxName 索引名称
+     * @param idxName
+     * @param id
      */
-    public static void deleteIndex(String idxName) {
-        if (!indexExist(idxName)) {
-            log.error(" idxName={} 索引不存在", idxName);
+    public static <T> void addSpecifyId(String idxName, String id, T t) {
+        if (Objects.isNull(idxName) || t == null) {
             return;
         }
         try {
-            esUtils.client.indices().delete(new DeleteIndexRequest(idxName), RequestOptions.DEFAULT);
+            esUtils.client.index(s ->
+                    s.index(idxName).id(id).document(t));
         } catch (IOException e) {
-            log.error("ES deleteIndex异常", e);
+            log.error("es插入指定id单条新数据异常:", e);
         }
     }
 
     /**
-     * 设置分片
+     * 修改文档自定义属性
      *
-     * @param request
+     * @param idxName
+     * @param id
+     * @param t
      */
-    public static void buildSetting(CreateIndexRequest request) {
-        request.settings(Settings.builder().put("index.number_of_shards", 3)
-                .put("index.number_of_replicas", 0));
+    public static <T> void update(String idxName, String id, T t) {
+        if (Objects.isNull(idxName) || t == null) {
+            return;
+        }
+        try {
+            esUtils.client.update(x -> x.index(idxName).id(id).doc(t), Object.class);
+        } catch (IOException e) {
+            log.error("es修改文档数据异常:", e);
+        }
     }
 
     /**
-     * 断某个index是否存在
+     * 批量新增
      *
-     * @param idxName
+     * @param indexName
+     * @param list
      * @return
      */
-    public static boolean indexExist(String idxName) {
-        GetIndexRequest request = new GetIndexRequest();
-        request.local(false);
-        request.humanReadable(true);
-        request.includeDefaults(false);
-        request.indices(idxName);
-        request.indicesOptions(IndicesOptions.lenientExpandOpen());
+    public static <T> void bulkSave(String indexName, List<T> list) {
+        if (Objects.isNull(indexName) || CollectionUtils.isEmpty(list)) {
+            return;
+        }
+        BulkRequest.Builder br = new BulkRequest.Builder();
+        //可不指定id es会自动生成id
+        list.forEach(e -> br.operations(op -> op
+                .index(idx -> idx.index(indexName).document(e))));
         try {
-            return esUtils.client.indices().exists(request, RequestOptions.DEFAULT);
+            esUtils.client.bulk(br.build());
         } catch (IOException e) {
-            log.error("ES indexExist查询SearchRequest异常", e);
-            throw new RuntimeException(e);
+            log.error("es批量新增数据异常:", e);
         }
     }
 
-
     /**
-     * 布尔查询
+     * 批量新增 指定id
      *
-     * @param searchRequest
+     * @param indexName
+     * @param list
      * @return
      */
-    public static SearchHits boolSearch(SearchRequest searchRequest) {
-        log.info("ES开始boolSearch查询SearchRequest:{}", searchRequest);
+    public static <T> void bulkSaveSpecifyId(String indexName, List<T> list) {
+        if (Objects.isNull(indexName) || CollectionUtils.isEmpty(list)) {
+            return;
+        }
+        BulkRequest.Builder br = new BulkRequest.Builder();
+        //对象id为es id
+        list.forEach(e -> br.operations(op -> op
+                .index(idx -> idx.index(indexName).id(JSON.parseObject((String) e).get("id").toString()).document(e))));
         try {
-            SearchResponse searchResponse = esUtils.client.search(searchRequest, RequestOptions.DEFAULT);
-            return searchResponse.getHits();
-        } catch (Exception e) {
-            log.error("ES boolSearch查询SearchRequest异常", e);
-            return null;
+            esUtils.client.bulk(br.build());
+        } catch (IOException e) {
+            log.error("es批量新增指定id数据异常:", e);
         }
     }
 
     /**
-     * 分组聚合查询
+     * ids批量删除
      *
-     * @param searchRequest
+     * @param indexName
+     * @param list
      * @return
      */
-    public static Aggregations groupBySearch(SearchRequest searchRequest) {
-        log.info("ES开始groupBySearch查询SearchRequest:{}", searchRequest);
+    public static <T> void bulkDel(String indexName, List<T> list) {
+        if (CollectionUtils.isEmpty(list)) {
+            return;
+        }
+        List<BulkOperation> bulkOperations = new ArrayList<>();
+        list.forEach(a ->
+                bulkOperations.add(BulkOperation.of(b ->
+                        b.delete(c -> c.id(JSON.parseObject((String) a).get("id").toString()))
+                )));
+        try {
+            esUtils.client.bulk(a -> a.index(indexName).operations(bulkOperations));
+        } catch (IOException e) {
+            log.error("es批量ids删除数据异常:", e);
+        }
+    }
+
+    /**
+     * term匹配 多次匹配
+     *
+     * @param index
+     * @param field
+     * @param fieldValues
+     * @return Object
+     */
+    public static List<Hit<Object>> advancedQueryByTerm(String index, String field, List<FieldValue> fieldValues) {
         try {
-            SearchResponse searchResponse = esUtils.client.search(searchRequest, RequestOptions.DEFAULT);
-            return searchResponse.getAggregations();
-        } catch (Exception e) {
-            log.error("ES groupBySearch查询SearchRequest异常", e);
+            SearchResponse<Object> response = esUtils.client.search(e -> e
+                    .index(index)
+                    .query(q -> q.terms(t -> t.field(field).terms(terms -> terms.value(fieldValues))))
+                    .query(q -> q.matchAll(m -> m)), Object.class);
+            return response.hits().hits();
+        } catch (IOException e) {
+            log.error("es term匹配多次匹配查询异常:", e);
             return null;
         }
     }
 
     /**
-     * 清除滚屏
+     * term匹配 单次匹配
      *
-     * @param scrollId
+     * @param index
+     * @param field
+     * @param value
+     * @return Object
      */
-    public static void clearScroll(String scrollId) {
-        if (scrollId != null) {
-            ClearScrollRequest clearScrollRequest = new ClearScrollRequest();
-            clearScrollRequest.addScrollId(scrollId);
-            try {
-                esUtils.client.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);
-                log.info("ES清除滚屏成功");
-            } catch (Exception e) {
-                log.error("ES清除滚屏出错:" + e.getMessage());
-            }
+    public static List<Hit<Object>> advancedQueryByTerm(String index, String field, long value) {
+        try {
+            SearchResponse<Object> response = esUtils.client.search(e -> e
+                    .index(index)
+                    .query(q -> q.term(t -> t.field(field).value(value)))
+                    .query(q -> q.matchAll(m -> m)), Object.class);
+            return response.hits().hits();
+        } catch (IOException e) {
+            log.error("es term匹配单次匹配查询异常:", e);
+            return null;
         }
     }
 
     /**
-     * 简单聚合查询
+     * 分页查询
      *
-     * @param countRequest
+     * @param index
+     * @param from
+     * @param size
      * @return
      */
-    public static long count(CountRequest countRequest) {
+    public static List<Hit<Object>> advancedQueryByPage(String index, Integer from, Integer size) {
         try {
-
-            log.info("开始ES查询indexName:{}的count", Arrays.toString(countRequest.indices()));
-            CountResponse count = esUtils.client.count(countRequest, RequestOptions.DEFAULT);
-            log.info("ES查询到:count={}", count.getCount());
-            return count.getCount();
-        } catch (Exception e) {
-            log.error("ES count异常", e);
-            return 0;
+            SearchResponse<Object> response = esUtils.client.search(e -> e
+                    .index(index)
+                    .query(q -> q.matchAll(m -> m))
+                    .from(from).size(size), Object.class);
+            return response.hits().hits();
+        } catch (IOException e) {
+            log.error("es 分页查询异常:", e);
+            return null;
         }
     }
 
     /**
-     * 批量新增
+     * multiMatch多field匹配
      *
      * @param indexName
-     * @param list
+     * @param fields
+     * @param query
+     * @param sortField
+     * @param order
+     * @param from
+     * @param size
      * @return
+     * @throws Exception
      */
-    public static <T> void bulkSave(String indexName, List<T> list) {
-        if (CollectionUtils.isEmpty(list)) {
-            return;
-        }
-        BulkRequest request = new BulkRequest();
-        for (Object t : list) {
-            String content = JSON.toJSONString(t);
-            String id = JSON.parseObject(content).get("id").toString();
-            request.add(new IndexRequest(indexName).id(id).source(content, XContentType.JSON));
-        }
+    public static List<Hit<Object>> queryMultiMatch(String indexName, List<String> fields, String query, String sortField, SortOrder order, Integer from, Integer size) {
         try {
-            BulkResponse bulkResponse = esUtils.client.bulk(request, RequestOptions.DEFAULT);
-            log.info("批量新增 操作es成功,{}", bulkResponse.status());
+            SearchResponse<Object> searchResponse = esUtils.client.search(e -> e
+                    .index(indexName)
+                    .query(q -> q.multiMatch(m -> m.fields(fields).query(query)))
+                    .sort(sort -> sort.field(f -> f.field(sortField).order(order)))
+                    .from(from).size(size), Object.class);
+            return searchResponse.hits().hits();
         } catch (IOException e) {
-            log.error("es批量新增数据异常:", e);
+            log.error("ES queryMultiMatch查询异常", e);
+            return null;
         }
     }
 
 
     /**
-     * 批量修改
+     * Range范围匹配
      *
      * @param indexName
-     * @param list
-     * @param script
+     * @param field
+     * @param gte       大于等于
+     * @param lte       小于等于
+     * @param sortField
+     * @param order
+     * @param from
+     * @param size
+     * @return
      */
-    public static <T> void bulkUpdate(String indexName, List<T> list, Script script) {
-        if (CollectionUtils.isEmpty(list)) {
-            return;
-        }
-        BulkRequest request = new BulkRequest();
-        for (Object t : list) {
-            String content = JSON.toJSONString(t);
-            String id = JSON.parseObject(content).get("id").toString();
-            UpdateRequest doc = new UpdateRequest(indexName, id);
-            request.add(doc.script(script));
+    public static List<Hit<Object>> queryBoolRange(String indexName, String field, Object gte, Object lte, String sortField, SortOrder order, Integer from, Integer size) {
+        try {
+            SearchResponse<Object> searchResponse = esUtils.client.search(e -> e
+                    .index(indexName)
+                    .query(q -> q.bool(b -> b.filter(f -> f.range(r -> r.field(field)
+                            .gte((Objects.isNull(gte) ? null : JsonData.of(gte)))
+                            .lte((Objects.isNull(lte) ? null : JsonData.of(lte)))))))
+                    .sort(sort -> sort.field(f -> f.field(sortField).order(order)))
+                    .from(from).size(size), Object.class);
+            return searchResponse.hits().hits();
+        } catch (IOException | ElasticsearchException e) {
+            log.error("ES queryBoolRange查询异常", e);
+            return null;
         }
+    }
+
+    /**
+     * filter过滤
+     *
+     * @param indexName
+     * @param excludes
+     * @param includes
+     * @param sortField
+     * @param order
+     * @param from
+     * @param size
+     * @return
+     */
+    public static List<Hit<Object>> queryFilter(String indexName, List<String> excludes, List<String> includes, String sortField, SortOrder order, Integer from, Integer size) {
         try {
-            BulkResponse bulkResponse = esUtils.client.bulk(request, RequestOptions.DEFAULT);
-            log.info("批量更新 操作es成功,{}", bulkResponse.status());
+            SearchResponse<Object> searchResponse = esUtils.client.search(e -> e
+                    .index(indexName)
+                    .query(q -> q.matchAll(m -> m))
+                    .source(s -> s.filter(f -> f.excludes(excludes).includes(includes)))
+                    .sort(sort -> sort.field(f -> f.field(sortField).order(order)))
+                    .from(from).size(size), Object.class);
+            return searchResponse.hits().hits();
         } catch (IOException e) {
-            log.error("es批量更新数据异常:", e);
+            log.error("ES queryFilter查询异常", e);
+            return null;
         }
     }
 
-
     /**
-     * 批量删除
+     * fuzzy模糊匹配
      *
      * @param indexName
-     * @param list
+     * @param field
+     * @param value
+     * @param fuzziness
+     * @param sortField
+     * @param order
+     * @param from
+     * @param size
      * @return
      */
-    public static <T> void bulkDel(String indexName, List<T> list) {
-        if (CollectionUtils.isEmpty(list)) {
-            return;
-        }
-        BulkRequest request = new BulkRequest();
-        for (Object t : list) {
-            String content = JSON.toJSONString(t);
-            String id = JSON.parseObject(content).get("id").toString();
-            request.add(new DeleteRequest(indexName).id(id));
-        }
+    public static List<Hit<Object>> queryFuzzy(String indexName, String field, String value, String fuzziness, String sortField, SortOrder order, Integer from, Integer size) {
         try {
-            BulkResponse bulkResponse = esUtils.client.bulk(request, RequestOptions.DEFAULT);
-            log.info("批量删除 操作es成功,{}", bulkResponse.status());
+            SearchResponse<Object> searchResponse = esUtils.client.search(e -> e
+                    .index(indexName)
+                    .query(q -> q.fuzzy(f -> f.field(field).value(value).fuzziness(fuzziness)))
+                    .sort(sort -> sort.field(f -> f.field(sortField).order(order)))
+                    .from(from).size(size), Object.class);
+            return searchResponse.hits().hits();
         } catch (IOException e) {
-            log.error("es批量删除数据异常:", e);
+            log.error("ES queryFuzzy查询异常", e);
+            return null;
         }
     }
 
     /**
-     * 根据条件更新
-     *
-     * @param idxName
-     * @param builder
-     * @param script
+     * @param indexName, field
+     * @return co.elastic.clients.elasticsearch._types.aggregations.Aggregate
+     * @desc: 分组聚合查询
+     * @author: yzc
+     * @date: 2023-06-12 17:36
      */
-    public static void updateByQuery(String idxName, SearchSourceBuilder builder, Script script) {
-        SearchRequest request = new SearchRequest(idxName);
-        request.source(builder);
-        UpdateByQueryRequest updateByQueryRequest = new UpdateByQueryRequest(idxName);
-        updateByQueryRequest.setQuery(builder.query());
-        updateByQueryRequest.setScript(script);
+    public static Aggregate queryGroupAggregation(String indexName, String field) {
         try {
-            esUtils.client.updateByQuery(updateByQueryRequest, RequestOptions.DEFAULT);
+            SearchResponse<Void> searchResponse = esUtils.client.search(
+                    b -> b.index(indexName).size(0)
+                            .aggregations(field, a -> a.terms(TermsAggregation.of(s -> s.field(field)))),
+                    Void.class);
+            return searchResponse.aggregations().get(field);
         } catch (IOException e) {
-            log.error("es根据条件更新数据异常:", e);
+            log.error("ES queryGroupAggregation查询异常", e);
+            return null;
         }
     }
 
     /**
-     * 条件删除
+     * 简单聚合查询
      *
-     * @param idxName
-     * @param builder
+     * @param countRequest
      * @return
-     * @throws IOException
      */
-    public static void deleteByQuery(String idxName, TermQueryBuilder builder) {
-        DeleteByQueryRequest request = new DeleteByQueryRequest(idxName);
-        request.setQuery(builder);
+    public static long count(CountRequest countRequest) {
         try {
-            BulkByScrollResponse response = esUtils.client.deleteByQuery(request, RequestOptions.DEFAULT);
-            log.info("删除操作状态", JSONArray.toJSONString(response.getStatus().getDeleted()));
+            log.info("开始ES查询indexName:{}的count", Arrays.toString(countRequest.index().toArray()));
+            CountResponse count = esUtils.client.count(countRequest);
+            return count.count();
         } catch (IOException e) {
-            log.error("es根据条件删除数据异常:", e);
+            log.error("ES count异常", e);
+            return 0;
         }
     }
 
     /**
-     * es根据id更新数据
+     * SearchRequest原生查询
      *
-     * @param idxName
-     * @param id
-     * @param script
+     * @param searchRequest
+     * @return
      */
-    public static void update(String idxName, String id, Script script) {
-        UpdateRequest updateRequest = new UpdateRequest(idxName, id);
-        updateRequest.script(script);
+    public static List<Hit<Object>> queryOriginal(SearchRequest searchRequest) {
+        //Query of = Query.of(q -> q.bool(b -> b.must(m -> m.match(match -> match.field("").query("")))));
         try {
-            esUtils.client.update(updateRequest, RequestOptions.DEFAULT);
+            SearchResponse<Object> searchResponse = esUtils.client.search(searchRequest, Object.class);
+            return searchResponse.hits().hits();
         } catch (IOException e) {
-            log.error("es根据id更新数据异常:", e);
+            log.error("ES queryOriginal查询异常", e);
+            return null;
         }
     }
 
     /**
-     * 插入单条
+     * Query原生查询
      *
-     * @param idxName
-     * @param t
-     * @param <T>
+     * @param indexName
+     * @param field
+     * @param query
+     * @param order
+     * @param from
+     * @param size
+     * @return
+     * @throws Exception
      */
-    public static <T> void bulk(String idxName, T t) {
-        if (Objects.isNull(idxName) || t == null) {
-            return;
-        }
-        BulkRequest request = new BulkRequest();
-        String content = JSON.toJSONString(t);
-        String id = JSON.parseObject(content).get("id").toString();
-        request.add(new IndexRequest(idxName).id(id).source(content, XContentType.JSON));
+    public static List<Hit<Object>> queryOriginal(String indexName, String field, Query query, SortOrder order, Integer from, Integer size) {
+        //Query of = Query.of(q -> q.bool(b -> b.must(m -> m.match(match -> match.field("").query("")))));
         try {
-            esUtils.client.bulk(request, RequestOptions.DEFAULT);
+            SearchResponse<Object> searchResponse = esUtils.client.search(e -> e
+                    .index(indexName)
+                    .query(query)
+                    .sort(sort -> sort.field(f -> f.field(field).order(order)))
+                    .from(from).size(size), Object.class);
+            return searchResponse.hits().hits();
         } catch (IOException e) {
-            log.error("es插入单条新数据异常:", e);
+            log.error("ES queryOriginal查询异常", e);
+            return null;
         }
     }
 

+ 16 - 10
sckw-common/sckw-common-elasticsearch/src/main/java/com/sckw/elasticsearch/service/es/autoconfigure/EsAutoConfiguration.java

@@ -1,6 +1,8 @@
 package com.sckw.elasticsearch.service.es.autoconfigure;
 
-
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
 import com.sckw.elasticsearch.service.es.EsUtils;
 import com.sckw.elasticsearch.service.es.constants.EsConstant;
 import com.sckw.elasticsearch.service.es.properties.EsProperties;
@@ -13,7 +15,10 @@ import org.apache.http.client.CredentialsProvider;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.nio.reactor.IOReactorConfig;
 import org.apache.http.message.BasicHeader;
-import org.elasticsearch.client.*;
+import org.elasticsearch.client.Node;
+import org.elasticsearch.client.NodeSelector;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestClientBuilder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -36,16 +41,16 @@ public class EsAutoConfiguration {
 
 
     @Bean
-    @ConditionalOnClass(RestHighLevelClient.class)
+    @ConditionalOnClass(ElasticsearchClient.class)
     @ConditionalOnMissingBean(EsUtils.class)
-    public EsUtils esUtils(RestHighLevelClient restHighLevelClient) {
+    public EsUtils esUtils(ElasticsearchClient elasticsearchClient) {
         log.info("---------------EsUtils 正在初始化");
-        return new EsUtils(restHighLevelClient);
+        return new EsUtils(elasticsearchClient);
     }
 
     @Bean
-    @ConditionalOnMissingBean(RestHighLevelClient.class)
-    public RestHighLevelClient restHighLevelClient() {
+    @ConditionalOnMissingBean(ElasticsearchClient.class)
+    public ElasticsearchClient restHighLevelClient() {
         log.info("---------------es配置正在加载,当前配置为:{}", esProperties);
         if (EsConstant.DEFAULT_HOST.equals(esProperties.getHostList())) {
             throw new RuntimeException("es配置错误,无法加载");
@@ -101,8 +106,9 @@ public class EsAutoConfiguration {
                 new UsernamePasswordCredentials(esProperties.getUsername(), esProperties.getPassword()));
         clientBuilder.setHttpClientConfigCallback(callback -> callback.setDefaultCredentialsProvider(credentialsProvider)
                 .setKeepAliveStrategy((response, context) -> TimeUnit.MINUTES.toMillis(3)));
-
-        //创建RestHighLevelClient客户端
-        return new RestHighLevelClient(clientBuilder);
+        //使用JSON映射器传输数据
+        RestClientTransport restClientTransport = new RestClientTransport(clientBuilder.build(), new JacksonJsonpMapper());
+        //创建API客户端
+        return new ElasticsearchClient(restClientTransport);
     }
 }

+ 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() {

+ 7 - 9
sckw-common/sckw-common-redis/src/main/java/com/sckw/redis/configure/RedissonConfiguration.java

@@ -2,7 +2,6 @@ package com.sckw.redis.configure;
 
 import org.redisson.Redisson;
 import org.redisson.api.RedissonClient;
-import org.redisson.codec.JsonJacksonCodec;
 import org.redisson.config.Config;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
@@ -15,28 +14,27 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class RedissonConfiguration {
 
-    @Value("${spring.data.redis.host}")
+    @Value("${spring.redis.host}")
     private String address;
 
-    @Value("${spring.data.redis.port}")
+    @Value("${spring.redis.port}")
     private String port;
 
-//    @Value("${spring.data.redis.password}")
-//    private String password;
+    @Value("${spring.redis.password}")
+    private String password;
 
-    @Value("${spring.data.redis.database}")
+    @Value("${spring.redis.database}")
     private String database;
 
-    @Value("${spring.data.redis.timeout}")
+    @Value("${spring.redis.timeout}")
     private String timeout;
 
     @Bean
     public RedissonClient redisson() {
         Config config = new Config();
-        config.setCodec(new JsonJacksonCodec());
         config.useSingleServer()
                 .setAddress(address())
-//                .setPassword(password)
+                .setPassword(password)
                 .setDatabase(Integer.parseInt(database))
                 .setConnectTimeout(Integer.parseInt(timeout));
         return Redisson.create(config);

+ 197 - 25
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,192 @@ 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");
+    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);
+    }
+
+    /**
+     * 尝试加锁,最多等待waitTime秒,上锁以后leaseTime秒自动解锁
+     *
+     * @param lockKey
+     * @param waitTime
+     * @param leaseTime
+     * @return
+     */
+    public static boolean tryLock(String lockKey, long waitTime, long leaseTime) {
+        RLock lock = redissonUtils.redissonClient.getLock(lockKey);
+        try {
+            return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            log.info("tryLock lockKey:{} waitTime:{} leaseTime:{}", lockKey, waitTime, leaseTime);
+            return false;
+        } finally {
+            lock.unlock();
         }
-        bucket.delete();
     }
 
 }

+ 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;
-    }
 }

+ 1 - 1
sckw-common/sckw-common-stream/src/main/java/com/sckw/stream/model/SckwMessage.java

@@ -41,7 +41,7 @@ public class SckwMessage {
     /**
      * 创建人
      */
-    private String createBy;
+    private Long createBy;
 
     /**
      * 推送用户

+ 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;
 }
 

+ 44 - 28
sckw-modules/sckw-example/src/main/java/com/sckw/example/controller/EsController.java

@@ -1,18 +1,20 @@
 package com.sckw.example.controller;
 
+import co.elastic.clients.elasticsearch._types.mapping.Property;
+import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
+import co.elastic.clients.elasticsearch.core.search.Hit;
+import co.elastic.clients.elasticsearch.indices.IndexSettings;
+import co.elastic.clients.util.ObjectBuilder;
 import com.sckw.elasticsearch.service.es.EsUtils;
-import com.sckw.example.model.Employees;
+import com.sckw.example.model.Product;
 import lombok.RequiredArgsConstructor;
 import org.apache.commons.compress.utils.Lists;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.search.SearchHits;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
+import java.util.function.Function;
 
 /**
  * @author: yzc
@@ -27,44 +29,58 @@ public class EsController {
 
     @GetMapping(value = "/createIndex")
     public void createIndex() {
-        String mappings = "{\n" +
-                "  \"properties\": {\n" +
-                "    \"id\": {\n" +
-                "      \"type\": \"keyword\"\n" +
-                "    },\n" +
-                "    \"name\": {\n" +
-                "      \"type\": \"text\"\n" +
-                "    }\n" + "  }\n" +
-                "}";
-        System.out.println("mapping is as follows: ");
-        System.out.println(mappings);
+        // 索引名
+        String indexName = "product002";
+
+        // 构建setting时,builder用到的lambda
+        Function<IndexSettings.Builder, ObjectBuilder<IndexSettings>> settingFn = sBuilder -> sBuilder
+                .index(iBuilder -> iBuilder
+                        // 三个分片
+                        .numberOfShards("3")
+                        // 一个副本
+                        .numberOfReplicas("1")
+                );
+
+        // 新的索引有三个字段,每个字段都有自己的property,这里依次创建
+        Property keywordProperty = Property.of(pBuilder -> pBuilder.keyword(kBuilder -> kBuilder.ignoreAbove(256)));
+        Property textProperty = Property.of(pBuilder -> pBuilder.text(tBuilder -> tBuilder));
+        Property integerProperty = Property.of(pBuilder -> pBuilder.integer(iBuilder -> iBuilder));
+
+        // // 构建mapping时,builder用到的lambda
+        Function<TypeMapping.Builder, ObjectBuilder<TypeMapping>> mappingFn = mBuilder -> mBuilder
+                .properties("name", keywordProperty)
+                .properties("description", textProperty)
+                .properties("price", integerProperty);
+
+        // 创建索引,并且指定了setting和mapping
+        EsUtils.createIndex(indexName, settingFn, mappingFn);
 
-        EsUtils.createIndex("employees", mappings);
     }
 
 
     @GetMapping(value = "/deleteIndex")
-    public void deleteIndex(@RequestParam(value = "indexName") String indexName) {
-        EsUtils.deleteIndex(indexName);
+    public void deleteIndex() {
+        EsUtils.delIndex("product002");
     }
 
     @GetMapping(value = "/bulkSave")
     public void bulkSave() {
-        List<Employees> list = Lists.newArrayList();
-        Employees nancy = Employees.builder().id("2").name("Nancy").build();
-        Employees jason = Employees.builder().id("3").name("Jason").build();
+        List<Product> list = Lists.newArrayList();
+        Product nancy = Product.builder().name("Nancy").description("试试").price(1000).build();
+        Product jason = Product.builder().name("Jason").description("玩玩").price(2000).build();
+        Product xason = Product.builder().name("xason").description("试试2").price(3000).build();
+        Product qason = Product.builder().name("qason").description("玩玩2").price(3000).build();
         list.add(nancy);
         list.add(jason);
-        EsUtils.bulkSave("employees", list);
+        list.add(xason);
+        list.add(qason);
+        EsUtils.bulkSave("product002", list);
 
     }
 
     @GetMapping(value = "/search")
     public void search() {
-        SearchRequest request = new SearchRequest("employees");
-        SearchSourceBuilder builder = new SearchSourceBuilder();
-        request.source(builder);
-        SearchHits hits = EsUtils.boolSearch(request);
-        System.out.println(hits);
+        List<Hit<Object>> list = EsUtils.advancedQueryByPage("product002", 3, 2);
+        System.out.println(list);
     }
 }

+ 22 - 0
sckw-modules/sckw-example/src/main/java/com/sckw/example/model/Product.java

@@ -0,0 +1,22 @@
+package com.sckw.example.model;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+
+/**
+ * @desc: TODO
+ * @author: yzc
+ * @date: 2023-06-12 17:37
+ */
+@Getter
+@Setter
+@ToString
+@Builder
+public class Product {
+    private String id;
+    private String name;
+    private String description;
+    private Integer price;
+}

+ 2 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/MessageApplication.java

@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.messaging.Message;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.FluxSink;
@@ -17,6 +18,7 @@ import java.util.function.Supplier;
 @EnableDubbo
 @EnableFeignClients({"com.sckw.*.api.feign"})
 @EnableDiscoveryClient
+@ComponentScan(basePackages = { "com.sckw.core","com.sckw.message"})
 @SpringBootApplication
 public class MessageApplication {
 

+ 14 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/constant/RedisConstant.java

@@ -0,0 +1,14 @@
+package com.sckw.message.constant;
+
+/**
+ * @desc: redis常量
+ * @author: yzc
+ * @date: 2023-06-09 11:27
+ */
+public class RedisConstant {
+
+    /**
+     * 短信验证码key
+     */
+    public static final String MESSAGE_SMS_VERIFY_CODE_KEY = "sckw:message:sms:verifyCode:%s";
+}

+ 17 - 2
sckw-modules/sckw-message/src/main/java/com/sckw/message/consumer/SckwMessageConsumer.java

@@ -1,19 +1,34 @@
 package com.sckw.message.consumer;
 
+import com.alibaba.fastjson.JSON;
+import com.sckw.message.service.SckwMessageHandlerService;
 import com.sckw.stream.model.SckwMessage;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 import java.util.function.Consumer;
 
+/**
+ * @desc: message消费相关
+ * @author: yzc
+ * @date: 2023-06-09 15:32
+ */
 @Configuration
+@RequiredArgsConstructor
 @Slf4j
 public class SckwMessageConsumer {
+    private final SckwMessageHandlerService sckwMessageHandlerService;
+
     @Bean
     public Consumer<SckwMessage> sckwMessage() {
-        return person -> {
-            System.out.println("sckwMessage: " + person);
+        return sckwMessage -> {
+            try {
+                sckwMessageHandlerService.handler(sckwMessage);
+            } catch (Exception e) {
+                log.error("处理message消息:{}异常", JSON.toJSONString(sckwMessage), e);
+            }
         };
     }
 }

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

@@ -1,31 +1,35 @@
 package com.sckw.message.consumer;
 
-import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson.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 java.util.function.Consumer;
 
+/**
+ * @desc: 短信消息消费
+ * @author: yzc
+ * @date: 2023-06-09 15:29
+ */
 @Configuration
+@RequiredArgsConstructor
 @Slf4j
 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("短信发送成功");
+                sckwSmsHandlerService.handler(sckwSms);
             } catch (Exception e) {
-                e.printStackTrace();
+                log.error("处理发送短信消息:{}异常", JSON.toJSONString(sckwSms), e);
             }
-            System.out.println("sckwSms: " + sckwSms);
         };
     }
 

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

@@ -0,0 +1,68 @@
+package com.sckw.message.controller;
+
+import com.sckw.core.web.response.HttpResult;
+import com.sckw.message.model.vo.req.DeleteMessagesReqVO;
+import com.sckw.message.model.vo.req.FindMessagesReqVO;
+import com.sckw.message.model.vo.req.ReadMessagesReqVO;
+import com.sckw.message.service.MessageService;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @desc: 消息相关接口
+ * @author: yzc
+ * @date: 2023-06-09 15:13
+ * @param
+ * @return
+ */
+@RestController
+@RequestMapping(value = "/kwmMessage")
+@RequiredArgsConstructor
+public class MessageController {
+
+    private final MessageService messageService;
+
+    /**
+     * @desc: 查找消息集合
+     * @author: yzc
+     * @date: 2023-06-09 15:12
+     * @param findMessagesReqVO
+     * @return com.sckw.core.web.response.HttpResult
+     */
+    @PostMapping(value = "/selectList", produces = MediaType.APPLICATION_JSON_VALUE)
+    public HttpResult selectList(@RequestBody @Valid FindMessagesReqVO findMessagesReqVO) {
+        return HttpResult.ok(messageService.selectMessages(findMessagesReqVO));
+    }
+
+    /**
+     * @desc: 消息已读
+     * @author: yzc
+     * @date: 2023-06-09 14:21
+     * @param readMessagesReqVO
+     * @return com.sckw.core.web.response.HttpResult
+     */
+    @PostMapping(value = "/read", produces = MediaType.APPLICATION_JSON_VALUE)
+    public HttpResult read(@RequestBody @Valid ReadMessagesReqVO readMessagesReqVO) {
+        messageService.read(readMessagesReqVO);
+        return HttpResult.ok();
+    }
+
+    /**
+     * @desc: 删除消息
+     * @author: yzc
+     * @date: 2023-06-09 14:21
+     * @param deleteMessagesReqVO
+     * @return com.sckw.core.web.response.HttpResult
+     */
+    @PostMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
+    public HttpResult delete(@RequestBody @Valid DeleteMessagesReqVO deleteMessagesReqVO) {
+        messageService.delete(deleteMessagesReqVO);
+        return HttpResult.ok();
+    }
+
+}

+ 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));
+    }
+
+}

+ 14 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmMessageMapper.java

@@ -0,0 +1,14 @@
+package com.sckw.message.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.message.model.KwmMessage;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @desc: 消息mapper
+ * @author: yzc
+ * @date: 2023-06-09 11:08
+ */
+@Mapper
+public interface KwmMessageMapper extends BaseMapper<KwmMessage> {
+}

+ 15 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/dao/KwmMessageUserMapper.java

@@ -0,0 +1,15 @@
+package com.sckw.message.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.message.model.KwmMessageUser;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @desc: 用户消息mapper
+ * @author: yzc
+ * @date: 2023-06-09 11:08
+ */
+@Mapper
+public interface KwmMessageUserMapper extends BaseMapper<KwmMessageUser> {
+
+}

+ 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> {
+
+}

+ 57 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmMessage.java

@@ -0,0 +1,57 @@
+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_message")
+public class KwmMessage extends BaseModel {
+    /**
+     * 消息分类
+     */
+    private String category;
+
+    /**
+     * 消息类型
+     */
+    private String type;
+
+    /**
+     * 消息标题
+     */
+    private String title;
+
+    /**
+     * 消息内容
+     */
+    private String content;
+
+    /**
+     * 消息跳转url
+     */
+    private String url;
+
+    /**
+     * 消息跳转参数
+     */
+    private String params;
+
+    /**
+     * 推送设备类型
+     */
+    private String clientType;
+
+
+}

+ 32 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/KwmMessageUser.java

@@ -0,0 +1,32 @@
+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_message_user")
+public class KwmMessageUser extends BaseModel {
+    /**
+     * 消息id
+     */
+    private Long msgId;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+
+}

+ 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;
+
+
+}

+ 36 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/DeleteMessagesReqVO.java

@@ -0,0 +1,36 @@
+package com.sckw.message.model.vo.req;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.NotBlank;
+
+import java.util.List;
+
+/**
+ * @desc: 删除消息请求参数
+ * @author: yzc
+ * @date: 2023-06-09 11:34
+ */
+@Getter
+@Setter
+@ToString
+public class DeleteMessagesReqVO {
+
+    /**
+     * 消息分类
+     */
+    @NotBlank(message = "消息分类不能为空")
+    private String category;
+
+    /**
+     * 消息类型
+     */
+    @NotBlank(message = "消息类型不能为空")
+    private String type;
+
+    /**
+     * 消息ids,不传则删除全部
+     */
+    private List<Long> msgIds;
+}

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

@@ -0,0 +1,30 @@
+package com.sckw.message.model.vo.req;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.NotBlank;
+
+/**
+ * @desc: 查找消息列表请求参数
+ * @author: yzc
+ * @date: 2023-06-09 11:34
+ */
+@Getter
+@Setter
+@ToString
+public class FindMessagesReqVO {
+
+    /**
+     * 消息分类
+     */
+    @NotBlank(message = "消息分类不能为空")
+    private String category;
+
+    /**
+     * 消息类型
+     */
+    private String type;
+
+
+}

+ 38 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/model/vo/req/ReadMessagesReqVO.java

@@ -0,0 +1,38 @@
+package com.sckw.message.model.vo.req;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.NotBlank;
+
+import java.util.List;
+
+/**
+ * @desc: 读取消息请求参数
+ * @author: yzc
+ * @date: 2023-06-09 11:34
+ */
+@Getter
+@Setter
+@ToString
+public class ReadMessagesReqVO {
+
+    /**
+     * 消息分类
+     */
+    @NotBlank(message = "消息分类不能为空")
+    private String category;
+
+    /**
+     * 消息类型
+     */
+    @NotBlank(message = "消息类型不能为空")
+    private String type;
+
+    /**
+     * 消息id集合 不传则更新全部为已读
+     */
+    private List<Long> msgIds;
+
+
+}

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

@@ -0,0 +1,28 @@
+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;
+
+/**
+ * @author: yzc
+ * @date: 2023-06-08 11:30
+ * @description: 发送短信验证码请求参数
+ */
+
+@Getter
+@Setter
+@ToString
+public class SendSmsVerifyCoderReqVO {
+
+    @NotBlank(message = "手机号不能为空!")
+    @Pattern(regexp = "^1[0-9]{10}$", message = "非法的手机号")
+    private String phone;
+
+
+    @NotNull(message = "有效时间不能为空!")
+    private Integer effectiveTime;
+}

+ 90 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmMessageService.java

@@ -0,0 +1,90 @@
+package com.sckw.message.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.sckw.core.utils.CollectionUtils;
+import com.sckw.core.utils.StringUtils;
+import com.sckw.message.dao.KwmMessageMapper;
+import com.sckw.message.model.KwmMessage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @desc: 消息相关service
+ * @author: yzc
+ * @date: 2023-06-09 10:58
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class KwmMessageService {
+
+    private final KwmMessageMapper kwmMessageMapper;
+
+
+    /**
+     * @desc: 根据条件获取消息列表
+     * @author: yzc
+     * @date: 2023-06-09 14:27
+     * @param msgIds, category, type, status
+     * @return java.util.List<com.sckw.message.model.KwmMessage>
+     */
+    public List<KwmMessage> getList(List<Long> msgIds, String category, String type, Integer status) {
+        LambdaQueryWrapper<KwmMessage> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(CollectionUtils.isNotEmpty(msgIds), KwmMessage::getId, msgIds)
+                .eq(StringUtils.isNotBlank(category), KwmMessage::getCategory, category)
+                .eq(StringUtils.isNotBlank(type), KwmMessage::getType, type)
+                .eq(Objects.nonNull(status), KwmMessage::getStatus, status)
+                .eq(KwmMessage::getDelFlag, 0).orderByAsc(KwmMessage::getStatus).orderByDesc(KwmMessage::getCreateTime);
+
+        return CollectionUtil.emptyIfNull(kwmMessageMapper.selectList(wrapper));
+    }
+
+
+    /**
+     * @desc: 更新已读根据消息ids
+     * @author: yzc
+     * @date: 2023-06-09 14:36
+     * @param msgIds
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void readByMsgIds(List<Long> msgIds) {
+        LambdaUpdateWrapper<KwmMessage> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(KwmMessage::getStatus, 1).in(KwmMessage::getId, msgIds);
+        kwmMessageMapper.update(null, wrapper);
+    }
+
+    /**
+     * @desc: 根据ids删除
+     * @author: yzc
+     * @date: 2023-06-09 15:08
+     * @param ids
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void delByMsgIds(List<Long> ids) {
+        LambdaUpdateWrapper<KwmMessage> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(KwmMessage::getDelFlag, 1).in(KwmMessage::getId, ids);
+        kwmMessageMapper.update(null, wrapper);
+    }
+
+    /**
+     * @desc: 插入消息
+     * @author: yzc
+     * @date: 2023-06-09 15:49
+     * @param kwmMessage
+     * @return java.lang.Long
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public Long insert(KwmMessage kwmMessage) {
+        kwmMessageMapper.insert(kwmMessage);
+        return kwmMessage.getId();
+    }
+}

+ 83 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/KwmMessageUserService.java

@@ -0,0 +1,83 @@
+package com.sckw.message.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.sckw.core.utils.CollectionUtils;
+import com.sckw.message.dao.KwmMessageUserMapper;
+import com.sckw.message.model.KwmMessageUser;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * @desc: 用户消息相关service
+ * @author: yzc
+ * @date: 2023-06-09 10:58
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class KwmMessageUserService {
+
+    private final KwmMessageUserMapper kwmMessageUserMapper;
+
+    /**
+     * @desc: 获取用户未删除消息ids
+     * @author: yzc
+     * @date: 2023-06-09 14:24
+     * @param userId
+     * @return java.lang.Long
+     */
+    public List<Long> getMsgIdsByUserId(Long userId) {
+        LambdaQueryWrapper<KwmMessageUser> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(KwmMessageUser::getUserId, userId).eq(KwmMessageUser::getDelFlag, 0);
+        List<KwmMessageUser> list = CollectionUtils.emptyIfNull(kwmMessageUserMapper.selectList(wrapper));
+        return list.stream().map(KwmMessageUser::getMsgId).toList();
+    }
+
+    /**
+     * @desc: 更新为已读根据用户id及消息ids
+     * @author: yzc
+     * @date: 2023-06-09 14:30
+     * @param userId, msgIds
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void readByUserAndMsgIds(Long userId, List<Long> msgIds) {
+        LambdaUpdateWrapper<KwmMessageUser> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(KwmMessageUser::getStatus, 1)
+                .eq(KwmMessageUser::getUserId, userId).in(KwmMessageUser::getMsgId, msgIds);
+        kwmMessageUserMapper.update(null, wrapper);
+    }
+
+    /**
+     * @desc: 根据用户删除消息
+     * @author: yzc
+     * @date: 2023-06-09 15:07
+     * @param userId, msgIds
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void delByUserAndMsgIds(long userId, List<Long> msgIds) {
+        LambdaUpdateWrapper<KwmMessageUser> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(KwmMessageUser::getDelFlag, 1)
+                .eq(KwmMessageUser::getUserId, userId).in(KwmMessageUser::getMsgId, msgIds);
+        kwmMessageUserMapper.update(null, wrapper);
+    }
+
+
+    /**
+     * @desc: 批量插入
+     * @author: yzc
+     * @date: 2023-06-09 15:58
+     * @param messageUsers
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void batchSave(List<KwmMessageUser> messageUsers) {
+        messageUsers.forEach(kwmMessageUserMapper::insert);
+    }
+}

+ 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);
+    }
+
+}

+ 106 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/MessageService.java

@@ -0,0 +1,106 @@
+package com.sckw.message.service;
+
+import com.sckw.core.utils.CollectionUtils;
+import com.sckw.message.model.KwmMessage;
+import com.sckw.message.model.KwmMessageUser;
+import com.sckw.message.model.vo.req.DeleteMessagesReqVO;
+import com.sckw.message.model.vo.req.FindMessagesReqVO;
+import com.sckw.message.model.vo.req.ReadMessagesReqVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @desc: 消息相关service
+ * @author: yzc
+ * @date: 2023-06-09 10:58
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class MessageService {
+
+    private final KwmMessageService kwmMessageService;
+    private final KwmMessageUserService kwmMessageUserService;
+
+
+    /**
+     * @desc: 查询消息列表
+     * @author: yzc
+     * @date: 2023-06-09 14:21
+     * @param params
+     * @return java.util.List<com.sckw.message.model.KwmMessage>
+     */
+    public List<KwmMessage> selectMessages(FindMessagesReqVO params) {
+        //TODO 当前线程获取用户id
+        List<Long> msgIds = kwmMessageUserService.getMsgIdsByUserId(1L);
+        if (CollectionUtils.isEmpty(msgIds)) {
+            return Collections.emptyList();
+        }
+        return kwmMessageService.getList(msgIds, params.getCategory(), params.getType(), null);
+    }
+
+    /**
+     * @desc: 更新消息已读
+     * @author: yzc
+     * @date: 2023-06-09 14:20
+     * @param reqVO
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void read(ReadMessagesReqVO reqVO) {
+        //TODO 当前线程获取用户id
+        List<Long> msgIds = kwmMessageUserService.getMsgIdsByUserId(1L);
+        if (CollectionUtils.isEmpty(msgIds)){
+            return;
+        }
+        List<Long> ids = reqVO.getMsgIds();
+        if (CollectionUtils.isNotEmpty(ids)) {
+            List<Long> list = ids.stream().filter(msgIds::contains).toList();
+            kwmMessageUserService.readByUserAndMsgIds(1L, list);
+            kwmMessageService.readByMsgIds(list);
+        } else {
+            List<KwmMessage> messageList = kwmMessageService.getList(msgIds, reqVO.getCategory(), reqVO.getType(), 0);
+            if (CollectionUtils.isEmpty(messageList)){
+                return;
+            }
+            List<Long> updateMsgIds = messageList.stream().map(KwmMessage::getId).toList();
+            kwmMessageUserService.readByUserAndMsgIds(1L, updateMsgIds);
+            kwmMessageService.readByMsgIds(updateMsgIds);
+        }
+    }
+
+    /**
+     * @desc: 删除消息
+     * @author: yzc
+     * @date: 2023-06-09 14:20
+     * @param reqVO
+     * @return void
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void delete(DeleteMessagesReqVO reqVO) {
+        //TODO 当前线程获取用户id
+        List<Long> msgIds = kwmMessageUserService.getMsgIdsByUserId(1L);
+        if (CollectionUtils.isEmpty(msgIds)){
+            return;
+        }
+        List<Long> ids = reqVO.getMsgIds();
+        if (CollectionUtils.isNotEmpty(ids)) {
+            List<Long> list = ids.stream().filter(msgIds::contains).toList();
+            kwmMessageUserService.delByUserAndMsgIds(1L, list);
+            kwmMessageService.delByMsgIds(list);
+        }else {
+            List<KwmMessage> messageList = kwmMessageService.getList(msgIds, reqVO.getCategory(), reqVO.getType(), null);
+            if (CollectionUtils.isEmpty(messageList)){
+                return;
+            }
+            List<Long> delMsgIds = messageList.stream().map(KwmMessage::getId).toList();
+            kwmMessageUserService.delByUserAndMsgIds(1L, delMsgIds);
+            kwmMessageService.delByMsgIds(delMsgIds);
+        }
+    }
+}

+ 63 - 0
sckw-modules/sckw-message/src/main/java/com/sckw/message/service/SckwMessageHandlerService.java

@@ -0,0 +1,63 @@
+package com.sckw.message.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
+import com.sckw.core.utils.StringUtils;
+import com.sckw.message.model.KwmMessage;
+import com.sckw.message.model.KwmMessageUser;
+import com.sckw.stream.enums.MessageEnum;
+import com.sckw.stream.model.SckwMessage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @desc: message消息处理service
+ * @author: yzc
+ * @date: 2023-06-09 11:01
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class SckwMessageHandlerService {
+
+    private final KwmMessageService kwmMessageService;
+    private final KwmMessageUserService kwmMessageUserService;
+
+
+    /**
+     * @param sckwMessage
+     * @return void
+     * @desc: message消息处理
+     * @author: yzc
+     * @date: 2023-06-09 15:33
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void handler(SckwMessage sckwMessage) {
+        String userIds = sckwMessage.getUserIds();
+        if (StringUtils.isBlank(userIds)) {
+            log.error("message消息处理用户id为空,不处理");
+            return;
+        }
+        MessageEnum messageEnum = sckwMessage.getMessageEnum();
+        KwmMessage kwmMessage = KwmMessage.builder().category(messageEnum.getCategory()).type(messageEnum.getType()).title(messageEnum.getTitle())
+                .content(messageEnum.getContent()).clientType(messageEnum.getPushType()).url(sckwMessage.getMsgUrl())
+                .params(JSON.toJSONString(sckwMessage.getParams())).build();
+        kwmMessage.setStatus(0);
+        kwmMessage.setCreateBy(sckwMessage.getCreateBy());
+        Long msgId = kwmMessageService.insert(kwmMessage);
+        List<String> userIdList = Arrays.asList(userIds.split(","));
+        List<KwmMessageUser> messageUsers = Lists.newArrayList();
+        userIdList.forEach(e -> {
+            KwmMessageUser messageUser = KwmMessageUser.builder().userId(Long.valueOf(e)).msgId(msgId).build();
+            messageUser.setStatus(0);
+            messageUser.setCreateBy(sckwMessage.getCreateBy());
+            messageUsers.add(messageUser);
+        });
+        kwmMessageUserService.batchSave(messageUsers);
+    }
+}

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

@@ -0,0 +1,48 @@
+package com.sckw.message.service;
+
+import com.alibaba.fastjson2.JSON;
+import com.sckw.message.constant.RedisConstant;
+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;
+
+    public void handler(SckwSms sckwSms) {
+        log.info("接收到发送短信消息:{},开始处理", JSON.toJSONString(sckwSms));
+        String key = getMessageSmsVerifyCodeKey(sckwSms.getTelephone());
+        Long effectiveTime = sckwSms.getEffectiveTime();
+        if (Boolean.FALSE.equals(RedissonUtils.tryLock(key, 10L, effectiveTime))) {
+            log.info("重复发送短信消息,不处理");
+            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(RedisConstant.MESSAGE_SMS_VERIFY_CODE_KEY, phone);
+    }
+}

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

@@ -0,0 +1,57 @@
+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.constant.RedisConstant;
+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;
+
+    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(RedisConstant.MESSAGE_SMS_VERIFY_CODE_KEY, phone);
+    }
+}

+ 3 - 3
sckw-modules/sckw-message/src/main/resources/bootstrap-dev.yml

@@ -53,9 +53,9 @@ spring:
           binder: defaultRabbit
           group: sckw
   rabbitmq:
-    username: admin
-    password: admin
-    host: 10.10.10.138
+    username: wph
+    password: Yy123...
+    host: 39.104.134.114
     port: 5672
     virtual-host: /
 

+ 31 - 6
sckw-modules/sckw-system/src/main/java/com/sckw/system/controller/SysDictController.java

@@ -6,6 +6,7 @@ import com.sckw.core.model.page.PageHelperUtil;
 import com.sckw.core.model.page.PageResult;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.system.model.SysDict;
+import com.sckw.system.model.SysDictType;
 import com.sckw.system.service.SysDictService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -26,16 +27,27 @@ public class SysDictController {
     private SysDictService sysDictService;
 
     /**
-     * @param id 主键ID
+     * @param params {type:字典类型、name:类型名称}
      * @return
-     * @description 根据主键查询
+     * @description 新增
      * @author zk
      * @date 2023/5/30
      **/
-    @GetMapping("/detail")
-    public HttpResult selectByKey(Long id) throws Exception {
-        SysDict sysDict = sysDictService.selectByKey(id);
-        return HttpResult.ok(sysDict);
+    @PostMapping("/addType")
+    public HttpResult addType(@RequestBody SysDictType params) throws Exception {
+        return sysDictService.addType(params);
+    }
+
+    /**
+     * @param params {id:主键ID、type:字典类型、name:类型名称}
+     * @return
+     * @description 更新
+     * @author zk
+     * @date 2023/5/30
+     **/
+    @PostMapping("/updateType")
+    public HttpResult updateType(@RequestBody SysDictType params) throws Exception {
+        return sysDictService.updateType(params);
     }
 
     /**
@@ -54,6 +66,19 @@ public class SysDictController {
         return HttpResult.ok(pageResult);
     }
 
+    /**
+     * @param id 主键ID
+     * @return
+     * @description 根据主键查询
+     * @author zk
+     * @date 2023/5/30
+     **/
+    @GetMapping("/detail")
+    public HttpResult selectByKey(Long id) throws Exception {
+        SysDict sysDict = sysDictService.selectByKey(id);
+        return HttpResult.ok(sysDict);
+    }
+
     /**
      * @param params {type:字典类型}
      * @return

+ 36 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/dao/SysDictTypeDao.java

@@ -0,0 +1,36 @@
+package com.sckw.system.dao;
+
+import com.sckw.system.model.SysDictType;
+import org.apache.ibatis.annotations.Mapper;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 字典类型
+ * @author zk
+ * @date 2023-05-30
+ */
+@Mapper
+public interface SysDictTypeDao {
+
+    /**
+     * 新增
+     * @param record
+     * @return
+     */
+    int insert(SysDictType record);
+
+    /**
+     * 更新
+     * @param record
+     * @return
+     */
+    int update(SysDictType record);
+
+    /**
+     * 查询
+     * @param params
+     * @return
+     */
+    List<SysDictType> findPage(Map<String, Object> params);
+}

+ 5 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/SysDict.java

@@ -11,6 +11,11 @@ import lombok.Data;
 @Data
 public class SysDict extends BaseModel {
 
+    /**
+     * 字典类型id
+     */
+    private Long dictId;
+
     /**
      * 选项值
      */

+ 24 - 0
sckw-modules/sckw-system/src/main/java/com/sckw/system/model/SysDictType.java

@@ -0,0 +1,24 @@
+package com.sckw.system.model;
+
+import com.sckw.core.model.base.BaseModel;
+import lombok.Data;
+
+/**
+ * 字典类型
+ * @author zk
+ * @date 2023-05-30
+ */
+@Data
+public class SysDictType extends BaseModel {
+
+    /**
+     * 字典类型名称
+     */
+    private String name;
+
+    /**
+     * 类型
+     */
+    private String type;
+
+}

+ 46 - 10
sckw-modules/sckw-system/src/main/java/com/sckw/system/service/SysDictService.java

@@ -4,7 +4,9 @@ import com.sckw.core.model.constant.Global;
 import com.sckw.core.utils.StringUtils;
 import com.sckw.core.web.response.HttpResult;
 import com.sckw.system.dao.SysDictDao;
+import com.sckw.system.dao.SysDictTypeDao;
 import com.sckw.system.model.SysDict;
+import com.sckw.system.model.SysDictType;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import java.util.List;
@@ -18,9 +20,53 @@ import java.util.Map;
 @Service
 public class SysDictService {
 
+    @Autowired
+    SysDictTypeDao sysDictTypeDao;
+
     @Autowired
     SysDictDao sysDictDao;
 
+    /**
+     * 添加新纪录
+     * @param params
+     * @return
+     * @throws Exception
+     */
+    public HttpResult addType(SysDictType params) throws Exception {
+        /*params.setId(new IdWorker(1).nextId());
+        params.setStatus(0);
+        params.setCreateBy(0L);
+        params.setCreateTime(new Date());
+        params.setUpdateBy(0L);
+        params.setUpdateTime(new Date());
+        params.setDelFlag(0);*/
+        params.setCreateBy(0L);
+        params.setUpdateBy(0L);
+        int count = sysDictTypeDao.insert(params);
+        return count > 0 ? HttpResult.ok("添加成功!") : HttpResult.error();
+    }
+
+    /**
+     * 更新记录
+     * @param params
+     * @return
+     * @throws Exception
+     */
+    public HttpResult updateType(SysDictType params) throws Exception {
+        int count = sysDictTypeDao.update(params);
+        return count > 0 ? HttpResult.ok("更新成功!") : HttpResult.error();
+    }
+
+    /**
+     * 分页查询
+     * @param params
+     * @return
+     * @throws Exception
+     */
+    public List<SysDictType> findPage(Map<String, Object> params) throws Exception{
+        return sysDictTypeDao.findPage(params);
+    }
+
     /**
      * 添加新纪录
      * @param params
@@ -87,16 +133,6 @@ public class SysDictService {
         return sysDictDao.selectByKey(key);
     }
 
-    /**
-     * 分页查询
-     * @param params
-     * @return
-     * @throws Exception
-     */
-    public List<SysDict> findPage(Map<String, Object> params) throws Exception{
-        return sysDictDao.findPage(params);
-    }
-
     /**
      * 查询
      * @param params

+ 11 - 1
sckw-modules/sckw-system/src/main/resources/mapper/SysDictDao.xml

@@ -3,6 +3,7 @@
 <mapper namespace="com.sckw.system.dao.SysDictDao">
   <resultMap id="BaseResultMap" type="com.sckw.system.model.SysDict">
     <id column="id" jdbcType="BIGINT" property="id" />
+    <id column="dict_id" jdbcType="BIGINT" property="dictId" />
     <result column="value" jdbcType="VARCHAR" property="value" />
     <result column="label" jdbcType="VARCHAR" property="label" />
     <result column="type" jdbcType="VARCHAR" property="type" />
@@ -19,7 +20,7 @@
   </resultMap>
 
   <sql id="Base_Column_List">
-    id, value, label, type, description, sort, parent_id, remark, status, create_by, 
+    id, dict_id, value, label, type, description, sort, parent_id, remark, status, create_by,
     create_time, update_by, update_time, del_flag
   </sql>
 
@@ -29,6 +30,9 @@
       <if test="id != null">
         id,
       </if>
+      <if test="dictId != null">
+        dict_id,
+      </if>
       <if test="value != null">
         value,
       </if>
@@ -73,6 +77,9 @@
       <if test="id != null">
         #{id,jdbcType=BIGINT},
       </if>
+      <if test="dictId != null">
+        #{dictId,jdbcType=BIGINT},
+      </if>
       <if test="value != null">
         #{value,jdbcType=VARCHAR},
       </if>
@@ -118,6 +125,9 @@
   <update id="update" parameterType="com.sckw.system.model.SysDict">
     update sys_dict
     <set>
+      <if test="dictId != null">
+        dict_id = #{dictId,jdbcType=BIGINT},
+      </if>
       <if test="value != null">
         value = #{value,jdbcType=VARCHAR},
       </if>

+ 137 - 0
sckw-modules/sckw-system/src/main/resources/mapper/SysDictTypeDao.xml

@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sckw.system.dao.SysDictTypeDao">
+  <resultMap id="BaseResultMap" type="com.sckw.system.model.SysDictType">
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="type" jdbcType="VARCHAR" property="type" />
+    <result column="remark" jdbcType="VARCHAR" property="remark" />
+    <result column="status" jdbcType="INTEGER" property="status" />
+    <result column="create_by" jdbcType="BIGINT" property="createBy" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="del_flag" jdbcType="INTEGER" property="delFlag" />
+  </resultMap>
+
+  <sql id="Base_Column_List">
+    id, name, type, remark, status, create_by,
+    create_time, update_by, update_time, del_flag
+  </sql>
+
+  <insert id="insert" parameterType="com.sckw.system.model.SysDictType">
+    insert into sys_dict_type
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        id,
+      </if>
+      <if test="name != null">
+        name,
+      </if>
+      <if test="type != null">
+        type,
+      </if>
+      <if test="remark != null">
+        remark,
+      </if>
+      <if test="status != null">
+        status,
+      </if>
+      <if test="createBy != null">
+        create_by,
+      </if>
+      <if test="createTime != null">
+        create_time,
+      </if>
+      <if test="updateBy != null">
+        update_by,
+      </if>
+      <if test="updateTime != null">
+        update_time,
+      </if>
+      <if test="delFlag != null">
+        del_flag,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="id != null">
+        #{id,jdbcType=BIGINT},
+      </if>
+      <if test="name != null">
+        #{name,jdbcType=VARCHAR},
+      </if>
+      <if test="type != null">
+        #{type,jdbcType=VARCHAR},
+      </if>
+      <if test="remark != null">
+        #{remark,jdbcType=VARCHAR},
+      </if>
+      <if test="status != null">
+        #{status,jdbcType=INTEGER},
+      </if>
+      <if test="createBy != null">
+        #{createBy,jdbcType=BIGINT},
+      </if>
+      <if test="createTime != null">
+        #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updateBy != null">
+        #{updateBy,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        #{updateTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="delFlag != null">
+        #{delFlag,jdbcType=INTEGER},
+      </if>
+    </trim>
+  </insert>
+
+  <update id="update" parameterType="com.sckw.system.model.SysDictType">
+    update sys_dict_type
+    <set>
+      <if test="name != null">
+        name = #{name,jdbcType=VARCHAR},
+      </if>
+      <if test="type != null">
+        type = #{type,jdbcType=VARCHAR},
+      </if>
+      <if test="remark != null">
+        remark = #{remark,jdbcType=VARCHAR},
+      </if>
+      <if test="status != null">
+        status = #{status,jdbcType=INTEGER},
+      </if>
+      <if test="createBy != null">
+        create_by = #{createBy,jdbcType=BIGINT},
+      </if>
+      <if test="createTime != null">
+        create_time = #{createTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="updateBy != null">
+        update_by = #{updateBy,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        update_time = #{updateTime,jdbcType=TIMESTAMP},
+      </if>
+      <if test="delFlag != null">
+        del_flag = #{delFlag,jdbcType=INTEGER},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+
+  <select id="findPage" resultMap="BaseResultMap" parameterType="java.util.Map" >
+    select
+    <include refid="Base_Column_List" />
+    from sys_dict_type
+    where del_flag = 0
+    <if test="type != null and type != ''">
+      and type = #{type, jdbcType=VARCHAR}
+    </if>
+    <if test="name != null and name != ''">
+      and name = #{name, jdbcType=VARCHAR}
+    </if>
+    ORDER BY type, create_time desc
+  </select>
+</mapper>