Kaynağa Gözat

代码优化

woody 8 ay önce
ebeveyn
işleme
2de2959471

+ 23 - 1
framework-base/src/main/java/com/chelvc/framework/base/context/Using.java

@@ -1,6 +1,7 @@
 package com.chelvc.framework.base.context;
 
 import com.chelvc.framework.common.model.Enumerable;
+import com.chelvc.framework.common.util.DateUtils;
 import lombok.Getter;
 
 /**
@@ -14,13 +15,18 @@ public enum Using implements Enumerable {
     /**
      * 历史首次
      */
-    NEWLY("历史首次"),
+    INITIAL("历史首次"),
 
     /**
      * 当日首次
      */
     DAILY("当日首次"),
 
+    /**
+     * 当前首次
+     */
+    NEWLY("当前首次"),
+
     /**
      * 普通请求
      */
@@ -34,4 +40,20 @@ public enum Using implements Enumerable {
     Using(String description) {
         this.description = description;
     }
+
+    /**
+     * 根据上次使用时间及注册时间结算使用类型
+     * <p>
+     * 如果距离上次使用时间超过15分钟我(900000毫秒)则视为重新进入系统
+     *
+     * @param latest      上次使用时间戳
+     * @param registering 用户注册时间戳
+     * @return 使用类型枚举
+     */
+    public static Using from(Long latest, Long registering) {
+        if (latest == null) {
+            return registering == null || registering < DateUtils.today().getTime() ? DAILY : INITIAL;
+        }
+        return System.currentTimeMillis() - latest > 900000 ? NEWLY : NORMAL;
+    }
 }

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

@@ -2,11 +2,14 @@ package com.chelvc.framework.redis.context;
 
 import java.io.Serializable;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
 import lombok.NonNull;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.core.script.RedisScript;
 
 /**
  * Redis Hash结构当日数据操作工具类
@@ -20,13 +23,23 @@ public final class RedisUserDailyHashHolder {
      */
     public static final String TYPE = "user";
 
+    /**
+     * Redis用户每天系统使用时间戳刷新脚本
+     */
+    private static final RedisScript<Object> USING_REFRESH_SCRIPT = new DefaultRedisScript<>(
+            "local value = redis.call('HGET', KEYS[1], 'using') " +
+                    "redis.call('HSET', KEYS[1], 'using', ARGV[1]) " +
+                    "if redis.call('TTL', KEYS[1]) < 1 then redis.call('EXPIRE', KEYS[1], ARGV[2]) end " +
+                    "return value", Object.class
+    );
+
     private RedisUserDailyHashHolder() {
     }
 
     /**
      * 获取Redis Hash结构用户当日数据
      *
-     * @param id  数据标识
+     * @param id  用户ID
      * @param key Hash键
      * @return Hash值
      */
@@ -38,7 +51,7 @@ public final class RedisUserDailyHashHolder {
      * 获取Redis Hash结构用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param key      Hash键
      * @return Hash值
      */
@@ -50,7 +63,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * 获取Redis Hash结构用户当日数据
      *
-     * @param id   数据标识
+     * @param id   用户ID
      * @param keys Hash键数组
      * @return Hash值列表
      */
@@ -62,7 +75,7 @@ public final class RedisUserDailyHashHolder {
      * 获取Redis Hash结构用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param keys     Hash键数组
      * @return Hash值列表
      */
@@ -74,7 +87,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * 获取Redis Hash结构用户当日数据
      *
-     * @param id   数据标识
+     * @param id   用户ID
      * @param keys Hash键集合
      * @return Hash值列表
      */
@@ -86,7 +99,7 @@ public final class RedisUserDailyHashHolder {
      * 获取Redis Hash结构用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param keys     Hash键集合
      * @return Hash值列表
      */
@@ -98,7 +111,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * 设置Redis Hash结构用户当日数据
      *
-     * @param id    数据标识
+     * @param id    用户ID
      * @param array Hash键/值数组
      * @return true/false
      */
@@ -109,7 +122,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * 设置Redis Hash结构用户当日数据
      *
-     * @param id  数据标识
+     * @param id  用户ID
      * @param map Hash键/值映射表
      * @return true/false
      */
@@ -121,7 +134,7 @@ public final class RedisUserDailyHashHolder {
      * 设置Redis Hash结构用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param array    Hash键/值数组
      * @return true/false
      */
@@ -134,7 +147,7 @@ public final class RedisUserDailyHashHolder {
      * 设置Redis Hash结构用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param map      Hash键/值映射表
      * @return true/false
      */
@@ -146,7 +159,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * Redis Hash结构用户当日数字自增1
      *
-     * @param id  数据标识
+     * @param id  用户ID
      * @param key Hash键
      * @return 增/减后数值
      */
@@ -157,7 +170,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * Redis Hash结构用户当日数字自增/减,delta < 0 时自减
      *
-     * @param id    数据标识
+     * @param id    用户ID
      * @param key   Hash键
      * @param delta 增/减值
      * @return 增/减后数值
@@ -170,7 +183,7 @@ public final class RedisUserDailyHashHolder {
      * Redis Hash结构用户当日数字自增1
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param key      Hash键
      * @return 增/减后数值
      */
@@ -183,7 +196,7 @@ public final class RedisUserDailyHashHolder {
      * Redis Hash结构用户当日数字自增/减,delta < 0 时自减
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param key      Hash键
      * @param delta    增/减值
      * @return 增/减后数值
@@ -196,7 +209,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * Redis Hash结构删除用户当日数据
      *
-     * @param id   数据标识
+     * @param id   用户ID
      * @param keys Hash键数组
      * @return 成功删除数量
      */
@@ -208,7 +221,7 @@ public final class RedisUserDailyHashHolder {
      * Redis Hash结构删除用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param keys     Hash键数组
      * @return 成功删除数量
      */
@@ -220,7 +233,7 @@ public final class RedisUserDailyHashHolder {
     /**
      * Redis Hash结构删除用户当日数据
      *
-     * @param id   数据标识
+     * @param id   用户ID
      * @param keys Hash键集合
      * @return 成功删除数量
      */
@@ -232,7 +245,7 @@ public final class RedisUserDailyHashHolder {
      * Redis Hash结构删除用户当日数据
      *
      * @param template Redis操作模版实例
-     * @param id       数据标识
+     * @param id       用户ID
      * @param keys     Hash键集合
      * @return 成功删除数量
      */
@@ -240,4 +253,27 @@ public final class RedisUserDailyHashHolder {
                               @NonNull Collection<String> keys) {
         return RedisDailyHashHolder.delete(template, TYPE, id, keys);
     }
+
+    /**
+     * 获取并刷新用户当日使用时间戳
+     *
+     * @param id 用户ID
+     * @return 上次使用时间戳
+     */
+    public static Long using(@NonNull Serializable id) {
+        return using(RedisContextHolder.getRedisTemplate(), id);
+    }
+
+    /**
+     * 获取并刷新用户当日使用时间戳
+     *
+     * @param template Redis操作模版实例
+     * @param id       用户ID
+     * @return 上次使用时间戳
+     */
+    public static Long using(@NonNull RedisTemplate<String, ?> template, @NonNull Serializable id) {
+        List<String> keys = Collections.singletonList(RedisDailyHashHolder.name(TYPE, id));
+        long duration = RedisDailyHashHolder.countdown().getSeconds();
+        return (Long) template.execute(USING_REFRESH_SCRIPT, keys, System.currentTimeMillis(), duration);
+    }
 }

+ 1 - 4
framework-security/src/main/java/com/chelvc/framework/security/token/RedisSessionValidator.java

@@ -6,7 +6,6 @@ import java.util.Objects;
 import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.SessionContextHolder;
 import com.chelvc.framework.base.context.Using;
-import com.chelvc.framework.common.util.DateUtils;
 import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.redis.context.RedisContextHolder;
 import com.chelvc.framework.redis.context.RedisHashHolder;
@@ -69,9 +68,7 @@ public class RedisSessionValidator extends DefaultSessionValidator {
         // 更新会话主体信息
         String mobile = (String) context.get(AuthorizeContextHolder.MOBILE);
         Long registering = (Long) context.get(AuthorizeContextHolder.REGISTERING);
-        long usage = RedisUserDailyHashHolder.increment(template, id, "usage");
-        Using using = usage > 1 || registering == null ? Using.NORMAL :
-                registering >= DateUtils.today().getTime() ? Using.NEWLY : Using.DAILY;
+        Using using = Using.from(RedisUserDailyHashHolder.using(template, id), registering);
         SessionContextHolder.setSession(id, using, scope, mobile, AuthorizeContextHolder.getAuthorities(jwt));
         return OAuth2TokenValidatorResult.success();
     }