woody 9 mēneši atpakaļ
vecāks
revīzija
f8af73ad18

+ 46 - 23
framework-common/src/main/java/com/chelvc/framework/common/util/DateUtils.java

@@ -5,6 +5,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
@@ -23,6 +24,14 @@ import lombok.NonNull;
  * @date 2024/1/30
  */
 public final class DateUtils {
+    /**
+     * 支持的倒计时间字段
+     */
+    private static final int[] COUNTDOWN_SUPPORT_FIELDS = new int[]{
+            Calendar.YEAR, Calendar.MONTH, Calendar.DATE,
+            Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND
+    };
+
     /**
      * 默认日期格式化处理器
      */
@@ -1038,13 +1047,47 @@ public final class DateUtils {
     }
 
     /**
-     * 获取目标日期时间倒计时(当前时间距置顶日期时间时长)
+     * 获取指定时间类型倒计时
      *
-     * @param datetime 目标日期时间
+     * @param type 时间类型
+     * @return 倒计时长
+     */
+    public static Duration countdown(int type) {
+        int index = Arrays.binarySearch(COUNTDOWN_SUPPORT_FIELDS, type);
+        AssertUtils.check(index > -1, () -> "Not support countdown type: " + type);
+        Calendar calendar = Calendar.getInstance();
+        calendar.add(COUNTDOWN_SUPPORT_FIELDS[index], 1);
+        for (int i = index + 1; i < COUNTDOWN_SUPPORT_FIELDS.length; i++) {
+            int field = COUNTDOWN_SUPPORT_FIELDS[i];
+            if (field == Calendar.MONTH) {
+                calendar.set(Calendar.MONTH, 0);
+            } else if (field == Calendar.HOUR) {
+                calendar.set(Calendar.HOUR_OF_DAY, 0);
+            } else {
+                calendar.set(field, field > Calendar.DATE ? 0 : 1);
+            }
+        }
+        return countdown(calendar.getTimeInMillis());
+    }
+
+    /**
+     * 获取目标日期时间倒计时
+     *
+     * @param datetime 日期时间
      * @return 倒计时长
      */
     public static Duration countdown(Date datetime) {
-        return datetime == null ? null : Duration.ofMillis(datetime.getTime() - System.currentTimeMillis());
+        return datetime == null ? null : countdown(datetime.getTime());
+    }
+
+    /**
+     * 获取目标日期时间倒计时
+     *
+     * @param expiration 时间戳
+     * @return 倒计时长
+     */
+    public static Duration countdown(long expiration) {
+        return Duration.ofMillis(Math.max(expiration - System.currentTimeMillis(), 1000));
     }
 
     /**
@@ -1322,24 +1365,4 @@ public final class DateUtils {
     public static long timestamp(long timestamp, boolean millis) {
         return millis ? timestamp : seconds(timestamp) * 1000;
     }
-
-    /**
-     * 获取当前时间距过期时间的时长
-     *
-     * @param expiration 过期时间
-     * @return 持续时长
-     */
-    public static Duration duration(@NonNull Date expiration) {
-        return duration(expiration.getTime());
-    }
-
-    /**
-     * 获取当前时间距过期时间的时长
-     *
-     * @param expiration 过期时间戳
-     * @return 持续时长
-     */
-    public static Duration duration(@NonNull long expiration) {
-        return Duration.ofMillis(Math.max(expiration - System.currentTimeMillis(), 1000));
-    }
 }

+ 6 - 7
framework-redis/src/main/java/com/chelvc/framework/redis/context/RedisContextHolder.java

@@ -386,8 +386,7 @@ public final class RedisContextHolder {
     public static <T> T execute(@NonNull RedisConnectionFactory factory,
                                 @NonNull Function<RedisConnection, T> function) {
         return execute(factory, function, e -> {
-            log.warn("Redis execute failed: {}", e.getMessage());
-            return null;
+            throw e;
         });
     }
 
@@ -400,7 +399,7 @@ public final class RedisContextHolder {
      * @return 执行结果
      */
     public static <T> T execute(@NonNull Function<RedisConnection, T> function,
-                                @NonNull Function<Exception, T> failure) {
+                                @NonNull Function<RuntimeException, T> failure) {
         return execute(getConnectionFactory(), function, failure);
     }
 
@@ -414,12 +413,12 @@ public final class RedisContextHolder {
      * @return 执行结果
      */
     public static <T> T execute(@NonNull RedisConnectionFactory factory, @NonNull Function<RedisConnection, T> function,
-                                @NonNull Function<Exception, T> failure) {
+                                @NonNull Function<RuntimeException, T> failure) {
         RedisConnection connection = null;
         try {
             connection = factory.getConnection();
             return function.apply(connection);
-        } catch (Exception e) {
+        } catch (RuntimeException e) {
             return failure.apply(e);
         } finally {
             if (connection != null) {
@@ -534,10 +533,10 @@ public final class RedisContextHolder {
             } catch (Exception e) {
                 connection.scriptingCommands().eval(UNLOCK_SCRIPT.getBytes(), ReturnType.INTEGER, 1, args);
             }
-            return true;
+            return null;
         }, e -> {
             log.warn("Redis unlock failed: {}", e.getMessage());
-            return false;
+            return null;
         });
     }
 

+ 13 - 12
framework-redis/src/main/java/com/chelvc/framework/redis/context/RedisDailyHashHolder.java

@@ -2,6 +2,7 @@ package com.chelvc.framework.redis.context;
 
 import java.io.Serializable;
 import java.time.Duration;
+import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -23,12 +24,12 @@ public final class RedisDailyHashHolder {
     }
 
     /**
-     * 获取当日时间周期
+     * 获取过期时间倒计时
      *
-     * @return 时间周期
+     * @return 倒计时长
      */
-    public static Duration duration() {
-        return DateUtils.duration(DateUtils.tomorrow());
+    public static Duration countdown() {
+        return DateUtils.countdown(Calendar.DATE);
     }
 
     /**
@@ -135,7 +136,7 @@ public final class RedisDailyHashHolder {
      * @return true/false
      */
     public static boolean set(@NonNull String type, @NonNull Serializable id, @NonNull Object... array) {
-        return ObjectUtils.notEmpty(array) && RedisHashHolder.set(name(type, id), array, duration());
+        return ObjectUtils.notEmpty(array) && RedisHashHolder.set(name(type, id), array, countdown());
     }
 
     /**
@@ -147,7 +148,7 @@ public final class RedisDailyHashHolder {
      * @return true/false
      */
     public static boolean set(@NonNull String type, @NonNull Serializable id, @NonNull Map<String, ?> map) {
-        return ObjectUtils.notEmpty(map) && RedisHashHolder.set(name(type, id), map, duration());
+        return ObjectUtils.notEmpty(map) && RedisHashHolder.set(name(type, id), map, countdown());
     }
 
     /**
@@ -161,7 +162,7 @@ public final class RedisDailyHashHolder {
      */
     public static boolean set(@NonNull RedisTemplate<String, ?> template, @NonNull String type,
                               @NonNull Serializable id, @NonNull Object... array) {
-        return ObjectUtils.notEmpty(array) && RedisHashHolder.set(template, name(type, id), array, duration());
+        return ObjectUtils.notEmpty(array) && RedisHashHolder.set(template, name(type, id), array, countdown());
     }
 
     /**
@@ -175,7 +176,7 @@ public final class RedisDailyHashHolder {
      */
     public static boolean set(@NonNull RedisTemplate<String, ?> template, @NonNull String type,
                               @NonNull Serializable id, @NonNull Map<String, ?> map) {
-        return ObjectUtils.notEmpty(map) && RedisHashHolder.set(template, name(type, id), map, duration());
+        return ObjectUtils.notEmpty(map) && RedisHashHolder.set(template, name(type, id), map, countdown());
     }
 
     /**
@@ -187,7 +188,7 @@ public final class RedisDailyHashHolder {
      * @return 增/减后数值
      */
     public static long increment(@NonNull String type, @NonNull Serializable id, @NonNull String key) {
-        return RedisHashHolder.increment(name(type, id), key, duration());
+        return RedisHashHolder.increment(name(type, id), key, countdown());
     }
 
     /**
@@ -200,7 +201,7 @@ public final class RedisDailyHashHolder {
      * @return 增/减后数值
      */
     public static long increment(@NonNull String type, @NonNull Serializable id, @NonNull String key, long delta) {
-        return RedisHashHolder.increment(name(type, id), key, delta, duration());
+        return RedisHashHolder.increment(name(type, id), key, delta, countdown());
     }
 
     /**
@@ -214,7 +215,7 @@ public final class RedisDailyHashHolder {
      */
     public static long increment(@NonNull RedisTemplate<String, ?> template, @NonNull String type,
                                  @NonNull Serializable id, @NonNull String key) {
-        return RedisHashHolder.increment(template, name(type, id), key, duration());
+        return RedisHashHolder.increment(template, name(type, id), key, countdown());
     }
 
     /**
@@ -229,7 +230,7 @@ public final class RedisDailyHashHolder {
      */
     public static long increment(@NonNull RedisTemplate<String, ?> template, @NonNull String type,
                                  @NonNull Serializable id, @NonNull String key, long delta) {
-        return RedisHashHolder.increment(template, name(type, id), key, delta, duration());
+        return RedisHashHolder.increment(template, name(type, id), key, delta, countdown());
     }
 
     /**

+ 6 - 4
framework-redis/src/main/java/com/chelvc/framework/redis/context/RedisHashHolder.java

@@ -27,14 +27,16 @@ public final class RedisHashHolder {
     /**
      * Redis带过期时间HMSET脚本
      */
-    private static final String SET_DURATION_SCRIPT =
-            "return redis.call('HMSET', KEYS[1], unpack(ARGV, 2)) and redis.call('EXPIRE', KEYS[1], ARGV[1])";
+    private static final String SET_DURATION_SCRIPT = "if redis.call('HMSET', KEYS[1], unpack(ARGV, 2)) then " +
+            "if redis.call('TTL', KEYS[1]) < tonumber(ARGV[1]) then redis.call('EXPIRE', KEYS[1], ARGV[1]) end " +
+            "return 1 end return 0";
 
     /**
      * Redis带过期时间HINCRBY脚本
      */
-    private static final String HINCRBY_DURATION_SCRIPT =
-            "return redis.call('HINCRBY', KEYS[1], ARGV[1], ARGV[2]) and redis.call('EXPIRE', KEYS[1], ARGV[3])";
+    private static final String HINCRBY_DURATION_SCRIPT = "if redis.call('HINCRBY', KEYS[1], ARGV[1], ARGV[2]) then " +
+            "if redis.call('TTL', KEYS[1]) < tonumber(ARGV[3]) then redis.call('EXPIRE', KEYS[1], ARGV[3]) end " +
+            "return 1 end return 0";
 
     /**
      * Redis带过期时间HMSET脚本SHA

+ 18 - 18
framework-redis/src/main/java/com/chelvc/framework/redis/context/RedisUserDailyHashHolder.java

@@ -31,7 +31,7 @@ public final class RedisUserDailyHashHolder {
      * @return Hash值
      */
     public static Object get(@NonNull Serializable id, @NonNull String key) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(TYPE, id, key);
+        return RedisDailyHashHolder.get(TYPE, id, key);
     }
 
     /**
@@ -44,7 +44,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static Object get(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                              @NonNull String key) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(template, TYPE, id, key);
+        return RedisDailyHashHolder.get(template, TYPE, id, key);
     }
 
     /**
@@ -55,7 +55,7 @@ public final class RedisUserDailyHashHolder {
      * @return Hash值列表
      */
     public static List<?> get(@NonNull Serializable id, @NonNull String... keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(TYPE, id, keys);
+        return RedisDailyHashHolder.get(TYPE, id, keys);
     }
 
     /**
@@ -68,7 +68,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static List<?> get(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull String... keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(template, TYPE, id, keys);
+        return RedisDailyHashHolder.get(template, TYPE, id, keys);
     }
 
     /**
@@ -79,7 +79,7 @@ public final class RedisUserDailyHashHolder {
      * @return Hash值列表
      */
     public static List<?> get(@NonNull Serializable id, @NonNull Collection<String> keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(TYPE, id, keys);
+        return RedisDailyHashHolder.get(TYPE, id, keys);
     }
 
     /**
@@ -92,7 +92,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static List<?> get(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull Collection<String> keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.get(template, TYPE, id, keys);
+        return RedisDailyHashHolder.get(template, TYPE, id, keys);
     }
 
     /**
@@ -103,7 +103,7 @@ public final class RedisUserDailyHashHolder {
      * @return true/false
      */
     public static boolean set(@NonNull Serializable id, @NonNull Object... array) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.set(TYPE, id, array);
+        return RedisDailyHashHolder.set(TYPE, id, array);
     }
 
     /**
@@ -114,7 +114,7 @@ public final class RedisUserDailyHashHolder {
      * @return true/false
      */
     public static boolean set(@NonNull Serializable id, @NonNull Map<String, ?> map) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.set(TYPE, id, map);
+        return RedisDailyHashHolder.set(TYPE, id, map);
     }
 
     /**
@@ -127,7 +127,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static boolean set(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull Object... array) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.set(template, TYPE, id, array);
+        return RedisDailyHashHolder.set(template, TYPE, id, array);
     }
 
     /**
@@ -140,7 +140,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static boolean set(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull Map<String, ?> map) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.set(template, TYPE, id, map);
+        return RedisDailyHashHolder.set(template, TYPE, id, map);
     }
 
     /**
@@ -151,7 +151,7 @@ public final class RedisUserDailyHashHolder {
      * @return 增/减后数值
      */
     public static long increment(@NonNull Serializable id, @NonNull String key) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.increment(TYPE, id, key);
+        return RedisDailyHashHolder.increment(TYPE, id, key);
     }
 
     /**
@@ -163,7 +163,7 @@ public final class RedisUserDailyHashHolder {
      * @return 增/减后数值
      */
     public static long increment(@NonNull Serializable id, @NonNull String key, long delta) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.increment(TYPE, id, key, delta);
+        return RedisDailyHashHolder.increment(TYPE, id, key, delta);
     }
 
     /**
@@ -176,7 +176,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static long increment(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                                  @NonNull String key) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.increment(template, TYPE, id, key);
+        return RedisDailyHashHolder.increment(template, TYPE, id, key);
     }
 
     /**
@@ -190,7 +190,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static long increment(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                                  @NonNull String key, long delta) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.increment(template, TYPE, id, key, delta);
+        return RedisDailyHashHolder.increment(template, TYPE, id, key, delta);
     }
 
     /**
@@ -201,7 +201,7 @@ public final class RedisUserDailyHashHolder {
      * @return 成功删除数量
      */
     public static long delete(Serializable id, @NonNull String... keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.delete(TYPE, id, keys);
+        return RedisDailyHashHolder.delete(TYPE, id, keys);
     }
 
     /**
@@ -214,7 +214,7 @@ public final class RedisUserDailyHashHolder {
      */
     public static long delete(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull String... keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.delete(template, TYPE, id, keys);
+        return RedisDailyHashHolder.delete(template, TYPE, id, keys);
     }
 
     /**
@@ -225,7 +225,7 @@ public final class RedisUserDailyHashHolder {
      * @return 成功删除数量
      */
     public static long delete(@NonNull Serializable id, @NonNull Collection<String> keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.delete(TYPE, id, keys);
+        return RedisDailyHashHolder.delete(TYPE, id, keys);
     }
 
     /**
@@ -238,6 +238,6 @@ public final class RedisUserDailyHashHolder {
      */
     public static long delete(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id,
                               @NonNull Collection<String> keys) {
-        return com.chelvc.framework.redis.context.RedisDailyHashHolder.delete(template, TYPE, id, keys);
+        return RedisDailyHashHolder.delete(template, TYPE, id, keys);
     }
 }