From 72d2dcc68f46e14a868838434b5bcf681beb55bc Mon Sep 17 00:00:00 2001
From: "jlc@yoc.tech" <JiangYuChen666>
Date: Thu, 10 Aug 2023 11:26:44 +0800
Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E5=B0=86=20redisCache=20=E7=9A=84?=
 =?UTF-8?q?=E6=89=AB=E6=8F=8F=E7=AD=96=E7=95=A5=E8=AE=BE=E7=BD=AE=E6=88=90?=
 =?UTF-8?q?=20scan?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../config/YudaoTenantAutoConfiguration.java  |  8 +++++--
 .../config/YudaoCacheAutoConfiguration.java   |  9 +++++---
 .../redis/config/YudaoCacheProperties.java    | 21 +++++++++++++++++++
 .../src/main/resources/application.yaml       |  2 ++
 4 files changed, 35 insertions(+), 5 deletions(-)
 create mode 100644 yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java

diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
index bc53c244e..cd4193abf 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
@@ -4,6 +4,7 @@ import cn.hutool.core.annotation.AnnotationUtil;
 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
 import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
@@ -27,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -124,10 +126,12 @@ public class YudaoTenantAutoConfiguration {
     @Bean
     @Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
     public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                                     RedisCacheConfiguration redisCacheConfiguration) {
+                                                     RedisCacheConfiguration redisCacheConfiguration,
+                                                     YudaoCacheProperties yudaoCacheProperties) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
         // 创建 TenantRedisCacheManager 对象
         return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index 1442e8a83..2797e2117 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -23,7 +24,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
  * Cache 配置类,基于 Redis 实现
  */
 @AutoConfiguration
-@EnableConfigurationProperties({CacheProperties.class})
+@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
 @EnableCaching
 public class YudaoCacheAutoConfiguration {
 
@@ -62,10 +63,12 @@ public class YudaoCacheAutoConfiguration {
 
     @Bean
     public RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                               RedisCacheConfiguration redisCacheConfiguration) {
+                                               RedisCacheConfiguration redisCacheConfiguration,
+                                               YudaoCacheProperties yudaoCacheProperties) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
         // 创建 TenantRedisCacheManager 对象
         return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
new file mode 100644
index 000000000..5b217f61f
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.redis.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * Cache 配置项
+ *
+ * @author
+ */
+@ConfigurationProperties("yudao.cache")
+@Data
+@Validated
+public class YudaoCacheProperties {
+
+    /**
+     * redis scan 一次返回数量
+     */
+    private Integer redisScanBatchSize = 30;
+}
diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml
index 3bc4d5e62..54c817872 100644
--- a/yudao-server/src/main/resources/application.yaml
+++ b/yudao-server/src/main/resources/application.yaml
@@ -204,6 +204,8 @@ yudao:
     order:
       app-id: 1 # 商户编号
       expire-time: 2h # 支付的过期时间
+  cache: # spring cache 相关配置
+    redis-scan-batch-size: 30 # redis scan 一次返回数量
 
 debug: false
 

From 47698bfc6c1d71d1e628595762e1984d10354c9c Mon Sep 17 00:00:00 2001
From: "jlc@yoc.tech" <JiangYuChen666>
Date: Thu, 10 Aug 2023 11:50:18 +0800
Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=E6=8B=93=E5=B1=95=20=E6=94=AF?=
 =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F=E6=97=B6?=
 =?UTF-8?q?=E9=97=B4=E7=9A=84=20RedisCacheManager=20=E4=BD=BF=E6=94=AF?=
 =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F=E6=97=B6?=
 =?UTF-8?q?=E9=97=B4=E5=8D=95=E4=BD=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../redis/core/TimeoutRedisCacheManager.java  | 38 +++++++++++++++++--
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
index cfdee653d..4de7fe57c 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.framework.redis.core;
 
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import org.springframework.boot.convert.DurationStyle;
 import org.springframework.cache.annotation.Cacheable;
@@ -13,8 +14,8 @@ import java.time.temporal.ChronoUnit;
 
 /**
  * 支持自定义过期时间的 {@link RedisCacheManager} 实现类
- *
- * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
+ * <p>
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为最后一个字母(支持的单位有:d天,h小时,m分钟,s秒),默认单位为秒
  *
  * @author 芋道源码
  */
@@ -42,10 +43,41 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
             // 移除 # 后面的 : 以及后面的内容,避免影响解析
             names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
             // 解析时间
-            Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
+            Duration duration = parseDuration(names[1]);
             cacheConfig = cacheConfig.entryTtl(duration);
         }
         return super.createRedisCache(names[0], cacheConfig);
     }
 
+    /**
+     * 解析 Duration
+     *
+     * @param ttlStr
+     * @return
+     */
+    private Duration parseDuration(String ttlStr) {
+        String timeUnit = StrUtil.subSuf(ttlStr, -1);
+        switch (timeUnit) {
+            case "d":
+                return Duration.ofDays(removeSuffix(ttlStr));
+            case "h":
+                return Duration.ofHours(removeSuffix(ttlStr));
+            case "m":
+                return Duration.ofMinutes(removeSuffix(ttlStr));
+            case "s":
+                return Duration.ofSeconds(removeSuffix(ttlStr));
+            default:
+                return Duration.ofSeconds(Long.parseLong(ttlStr));
+        }
+    }
+
+    /**
+     * 移除多余的后缀
+     *
+     * @param ttlStr
+     * @return
+     */
+    private Long removeSuffix(String ttlStr) {
+        return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
+    }
 }

From e1fe21f24c4769e7cc47a6e750787b7ce7f24040 Mon Sep 17 00:00:00 2001
From: wanwan <913752709@qq.com>
Date: Thu, 10 Aug 2023 15:26:25 +0800
Subject: [PATCH 3/6] =?UTF-8?q?Revert=20"feat:=20=E5=B0=86=20redisCache=20?=
 =?UTF-8?q?=E7=9A=84=E6=89=AB=E6=8F=8F=E7=AD=96=E7=95=A5=E8=AE=BE=E7=BD=AE?=
 =?UTF-8?q?=E6=88=90=20scan"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 72d2dcc68f46e14a868838434b5bcf681beb55bc.
---
 .../config/YudaoTenantAutoConfiguration.java  |  8 ++-----
 .../config/YudaoCacheAutoConfiguration.java   |  9 +++-----
 .../redis/config/YudaoCacheProperties.java    | 21 -------------------
 .../src/main/resources/application.yaml       |  2 --
 4 files changed, 5 insertions(+), 35 deletions(-)
 delete mode 100644 yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java

diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
index cd4193abf..bc53c244e 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
@@ -4,7 +4,6 @@ import cn.hutool.core.annotation.AnnotationUtil;
 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
-import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
 import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
@@ -28,7 +27,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
-import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -126,12 +124,10 @@ public class YudaoTenantAutoConfiguration {
     @Bean
     @Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
     public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                                     RedisCacheConfiguration redisCacheConfiguration,
-                                                     YudaoCacheProperties yudaoCacheProperties) {
+                                                     RedisCacheConfiguration redisCacheConfiguration) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
-                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
         // 创建 TenantRedisCacheManager 对象
         return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index 2797e2117..1442e8a83 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -8,7 +8,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
-import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -24,7 +23,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
  * Cache 配置类,基于 Redis 实现
  */
 @AutoConfiguration
-@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
+@EnableConfigurationProperties({CacheProperties.class})
 @EnableCaching
 public class YudaoCacheAutoConfiguration {
 
@@ -63,12 +62,10 @@ public class YudaoCacheAutoConfiguration {
 
     @Bean
     public RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                               RedisCacheConfiguration redisCacheConfiguration,
-                                               YudaoCacheProperties yudaoCacheProperties) {
+                                               RedisCacheConfiguration redisCacheConfiguration) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
-                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
         // 创建 TenantRedisCacheManager 对象
         return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
deleted file mode 100644
index 5b217f61f..000000000
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.framework.redis.config;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.validation.annotation.Validated;
-
-/**
- * Cache 配置项
- *
- * @author
- */
-@ConfigurationProperties("yudao.cache")
-@Data
-@Validated
-public class YudaoCacheProperties {
-
-    /**
-     * redis scan 一次返回数量
-     */
-    private Integer redisScanBatchSize = 30;
-}
diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml
index 54c817872..3bc4d5e62 100644
--- a/yudao-server/src/main/resources/application.yaml
+++ b/yudao-server/src/main/resources/application.yaml
@@ -204,8 +204,6 @@ yudao:
     order:
       app-id: 1 # 商户编号
       expire-time: 2h # 支付的过期时间
-  cache: # spring cache 相关配置
-    redis-scan-batch-size: 30 # redis scan 一次返回数量
 
 debug: false
 

From c4a7da92333ffae26f8a2d666e72fb1564dc25a1 Mon Sep 17 00:00:00 2001
From: wanwan <913752709@qq.com>
Date: Thu, 10 Aug 2023 15:26:31 +0800
Subject: [PATCH 4/6] =?UTF-8?q?Revert=20"feat:=20=E6=8B=93=E5=B1=95=20?=
 =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F?=
 =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=9A=84=20RedisCacheManager=20=E4=BD=BF?=
 =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F?=
 =?UTF-8?q?=E6=97=B6=E9=97=B4=E5=8D=95=E4=BD=8D"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit 47698bfc6c1d71d1e628595762e1984d10354c9c.
---
 .../redis/core/TimeoutRedisCacheManager.java  | 38 ++-----------------
 1 file changed, 3 insertions(+), 35 deletions(-)

diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
index 4de7fe57c..cfdee653d 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
@@ -1,6 +1,5 @@
 package cn.iocoder.yudao.framework.redis.core;
 
-import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import org.springframework.boot.convert.DurationStyle;
 import org.springframework.cache.annotation.Cacheable;
@@ -14,8 +13,8 @@ import java.time.temporal.ChronoUnit;
 
 /**
  * 支持自定义过期时间的 {@link RedisCacheManager} 实现类
- * <p>
- * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为最后一个字母(支持的单位有:d天,h小时,m分钟,s秒),默认单位为秒
+ *
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
  *
  * @author 芋道源码
  */
@@ -43,41 +42,10 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
             // 移除 # 后面的 : 以及后面的内容,避免影响解析
             names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
             // 解析时间
-            Duration duration = parseDuration(names[1]);
+            Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
             cacheConfig = cacheConfig.entryTtl(duration);
         }
         return super.createRedisCache(names[0], cacheConfig);
     }
 
-    /**
-     * 解析 Duration
-     *
-     * @param ttlStr
-     * @return
-     */
-    private Duration parseDuration(String ttlStr) {
-        String timeUnit = StrUtil.subSuf(ttlStr, -1);
-        switch (timeUnit) {
-            case "d":
-                return Duration.ofDays(removeSuffix(ttlStr));
-            case "h":
-                return Duration.ofHours(removeSuffix(ttlStr));
-            case "m":
-                return Duration.ofMinutes(removeSuffix(ttlStr));
-            case "s":
-                return Duration.ofSeconds(removeSuffix(ttlStr));
-            default:
-                return Duration.ofSeconds(Long.parseLong(ttlStr));
-        }
-    }
-
-    /**
-     * 移除多余的后缀
-     *
-     * @param ttlStr
-     * @return
-     */
-    private Long removeSuffix(String ttlStr) {
-        return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
-    }
 }

From 64c8dd62929373bf627bf2d6a30918d66beedce2 Mon Sep 17 00:00:00 2001
From: wanwan <913752709@qq.com>
Date: Thu, 10 Aug 2023 15:26:47 +0800
Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=E6=8B=93=E5=B1=95=20=E6=94=AF?=
 =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F=E6=97=B6?=
 =?UTF-8?q?=E9=97=B4=E7=9A=84=20RedisCacheManager=20=E4=BD=BF=E6=94=AF?=
 =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E8=BF=87=E6=9C=9F=E6=97=B6?=
 =?UTF-8?q?=E9=97=B4=E5=8D=95=E4=BD=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../redis/core/TimeoutRedisCacheManager.java  | 38 +++++++++++++++++--
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
index cfdee653d..4de7fe57c 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.framework.redis.core;
 
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
 import org.springframework.boot.convert.DurationStyle;
 import org.springframework.cache.annotation.Cacheable;
@@ -13,8 +14,8 @@ import java.time.temporal.ChronoUnit;
 
 /**
  * 支持自定义过期时间的 {@link RedisCacheManager} 实现类
- *
- * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
+ * <p>
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为最后一个字母(支持的单位有:d天,h小时,m分钟,s秒),默认单位为秒
  *
  * @author 芋道源码
  */
@@ -42,10 +43,41 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
             // 移除 # 后面的 : 以及后面的内容,避免影响解析
             names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
             // 解析时间
-            Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
+            Duration duration = parseDuration(names[1]);
             cacheConfig = cacheConfig.entryTtl(duration);
         }
         return super.createRedisCache(names[0], cacheConfig);
     }
 
+    /**
+     * 解析 Duration
+     *
+     * @param ttlStr
+     * @return
+     */
+    private Duration parseDuration(String ttlStr) {
+        String timeUnit = StrUtil.subSuf(ttlStr, -1);
+        switch (timeUnit) {
+            case "d":
+                return Duration.ofDays(removeSuffix(ttlStr));
+            case "h":
+                return Duration.ofHours(removeSuffix(ttlStr));
+            case "m":
+                return Duration.ofMinutes(removeSuffix(ttlStr));
+            case "s":
+                return Duration.ofSeconds(removeSuffix(ttlStr));
+            default:
+                return Duration.ofSeconds(Long.parseLong(ttlStr));
+        }
+    }
+
+    /**
+     * 移除多余的后缀
+     *
+     * @param ttlStr
+     * @return
+     */
+    private Long removeSuffix(String ttlStr) {
+        return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
+    }
 }

From 134e5ca20fb167d489bb53b7d5942fa89fc466bd Mon Sep 17 00:00:00 2001
From: wanwan <913752709@qq.com>
Date: Thu, 10 Aug 2023 15:26:48 +0800
Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=E5=B0=86=20redisCache=20=E7=9A=84?=
 =?UTF-8?q?=E6=89=AB=E6=8F=8F=E7=AD=96=E7=95=A5=E8=AE=BE=E7=BD=AE=E6=88=90?=
 =?UTF-8?q?=20scan?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../config/YudaoTenantAutoConfiguration.java  |  8 +++++--
 .../config/YudaoCacheAutoConfiguration.java   |  9 +++++---
 .../redis/config/YudaoCacheProperties.java    | 21 +++++++++++++++++++
 .../src/main/resources/application.yaml       |  2 ++
 4 files changed, 35 insertions(+), 5 deletions(-)
 create mode 100644 yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java

diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
index bc53c244e..cd4193abf 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
@@ -4,6 +4,7 @@ import cn.hutool.core.annotation.AnnotationUtil;
 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
 import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
@@ -27,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -124,10 +126,12 @@ public class YudaoTenantAutoConfiguration {
     @Bean
     @Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
     public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                                     RedisCacheConfiguration redisCacheConfiguration) {
+                                                     RedisCacheConfiguration redisCacheConfiguration,
+                                                     YudaoCacheProperties yudaoCacheProperties) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
         // 创建 TenantRedisCacheManager 对象
         return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index 1442e8a83..2797e2117 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
 import org.springframework.data.redis.cache.RedisCacheConfiguration;
 import org.springframework.data.redis.cache.RedisCacheManager;
 import org.springframework.data.redis.cache.RedisCacheWriter;
@@ -23,7 +24,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
  * Cache 配置类,基于 Redis 实现
  */
 @AutoConfiguration
-@EnableConfigurationProperties({CacheProperties.class})
+@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
 @EnableCaching
 public class YudaoCacheAutoConfiguration {
 
@@ -62,10 +63,12 @@ public class YudaoCacheAutoConfiguration {
 
     @Bean
     public RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,
-                                               RedisCacheConfiguration redisCacheConfiguration) {
+                                               RedisCacheConfiguration redisCacheConfiguration,
+                                               YudaoCacheProperties yudaoCacheProperties) {
         // 创建 RedisCacheWriter 对象
         RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
-        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+                BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
         // 创建 TenantRedisCacheManager 对象
         return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
     }
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
new file mode 100644
index 000000000..5b217f61f
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.framework.redis.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * Cache 配置项
+ *
+ * @author
+ */
+@ConfigurationProperties("yudao.cache")
+@Data
+@Validated
+public class YudaoCacheProperties {
+
+    /**
+     * redis scan 一次返回数量
+     */
+    private Integer redisScanBatchSize = 30;
+}
diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml
index 3bc4d5e62..54c817872 100644
--- a/yudao-server/src/main/resources/application.yaml
+++ b/yudao-server/src/main/resources/application.yaml
@@ -204,6 +204,8 @@ yudao:
     order:
       app-id: 1 # 商户编号
       expire-time: 2h # 支付的过期时间
+  cache: # spring cache 相关配置
+    redis-scan-batch-size: 30 # redis scan 一次返回数量
 
 debug: false