From e9bfa1396ff47d171b3052a606e0931e6f93cc9c Mon Sep 17 00:00:00 2001
From: houzhongjian <houzhongyi@126.com>
Date: 星期四, 10 四月 2025 12:05:23 +0800
Subject: [PATCH] 还原framework代码

---
 iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java |   86 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java b/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java
new file mode 100644
index 0000000..de86678
--- /dev/null
+++ b/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java
@@ -0,0 +1,86 @@
+package com.iailab.framework.redis.core;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.redis.cache.RedisCache;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+
+import java.time.Duration;
+
+/**
+ * 支持自定义过期时间的 {@link RedisCacheManager} 实现类
+ *
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间。
+ * 单位为最后一个字母(支持的单位有:d 天,h 小时,m 分钟,s 秒),默认单位为 s 秒
+ *
+ * @author iailab
+ */
+public class TimeoutRedisCacheManager extends RedisCacheManager {
+
+    private static final String SPLIT = "#";
+
+    public TimeoutRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
+        super(cacheWriter, defaultCacheConfiguration);
+    }
+
+    @Override
+    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
+        if (StrUtil.isEmpty(name)) {
+            return super.createRedisCache(name, cacheConfig);
+        }
+        // 如果使用 # 分隔,大小不为 2,则说明不使用自定义过期时间
+        String[] names = StrUtil.splitToArray(name, SPLIT);
+        if (names.length != 2) {
+            return super.createRedisCache(name, cacheConfig);
+        }
+
+        // 核心:通过修改 cacheConfig 的过期时间,实现自定义过期时间
+        if (cacheConfig != null) {
+            // 移除 # 后面的 : 以及后面的内容,避免影响解析
+            String ttlStr = StrUtil.subBefore(names[1], StrUtil.COLON, false); // 获得 ttlStr 时间部分
+            names[1] = StrUtil.subAfter(names[1], ttlStr, false); // 移除掉 ttlStr 时间部分
+            // 解析时间
+            Duration duration = parseDuration(ttlStr);
+            cacheConfig = cacheConfig.entryTtl(duration);
+        }
+
+        // 创建 RedisCache 对象,需要忽略掉 ttlStr
+        return super.createRedisCache(names[0] + names[1], cacheConfig);
+    }
+
+    /**
+     * 解析过期时间 Duration
+     *
+     * @param ttlStr 过期时间字符串
+     * @return 过期时间 Duration
+     */
+    private Duration parseDuration(String ttlStr) {
+        String timeUnit = StrUtil.subSuf(ttlStr, -1);
+        switch (timeUnit) {
+            case "d":
+                return Duration.ofDays(removeDurationSuffix(ttlStr));
+            case "h":
+                return Duration.ofHours(removeDurationSuffix(ttlStr));
+            case "m":
+                return Duration.ofMinutes(removeDurationSuffix(ttlStr));
+            case "s":
+                return Duration.ofSeconds(removeDurationSuffix(ttlStr));
+            default:
+                return Duration.ofSeconds(Long.parseLong(ttlStr));
+        }
+    }
+
+    /**
+     * 移除多余的后缀,返回具体的时间
+     *
+     * @param ttlStr 过期时间字符串
+     * @return 时间
+     */
+    private Long removeDurationSuffix(String ttlStr) {
+        return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
+    }
+
+}

--
Gitblit v1.9.3