Przeglądaj źródła

用户端登录 可登录多个设备同时在线

qinxuyang 1 tydzień temu
rodzic
commit
994b93df0f

+ 8 - 0
alien-gateway/src/main/java/shop/alien/gateway/config/BaseRedisService.java

@@ -83,6 +83,14 @@ public class BaseRedisService {
     }
 
     /**
+     * 判断 Set 中是否包含指定成员
+     */
+    public boolean isSetMember(String key, String member) {
+        Boolean m = stringRedisTemplate.opsForSet().isMember(key, member);
+        return m != null && m;
+    }
+
+    /**
      * 添加String值, 不设置过期时间
      *
      * @param key   键

+ 22 - 11
alien-gateway/src/main/java/shop/alien/gateway/config/JwtTokenFilter.java

@@ -122,20 +122,31 @@ public class JwtTokenFilter implements GlobalFilter, Ordered {
                     //不限制
                     return allowChain(exchange, chain);
                 } else if ("user".equals(deviceType) || "miniprogram_user".equals(deviceType)) {
-                    // 用户/小程序:兼容 openid(点餐小程序存 miniprogram_user_token:{openid})与手机号(miniprogram_user_{phone} / user_{phone})
-                    List<String> candidateKeys = new ArrayList<>();
+                    // 用户/小程序:openid 仍为单 string;手机号维度支持多设备 Set(user_sessions: / miniprogram_user_sessions:)并兼容旧 string key
                     if (StringUtils.isNotBlank(openid)) {
-                        candidateKeys.add("miniprogram_user_token:" + openid);
-                    }
-                    if (StringUtils.isNotBlank(phone)) {
-                        candidateKeys.add("miniprogram_user_" + phone);
-                        candidateKeys.add("user_" + phone);
-                    }
-                    for (String key : candidateKeys) {
-                        String val = baseRedisService.getString(key);
+                        String val = baseRedisService.getString("miniprogram_user_token:" + openid);
                         if (StringUtils.isNotBlank(val) && token.equals(val)) {
                             redisVal = val;
-                            break;
+                        }
+                    }
+                    if (redisVal == null && StringUtils.isNotBlank(phone)) {
+                        if (baseRedisService.isSetMember("miniprogram_user_sessions:" + phone, token)) {
+                            redisVal = token;
+                        } else {
+                            String mpVal = baseRedisService.getString("miniprogram_user_" + phone);
+                            if (StringUtils.isNotBlank(mpVal) && token.equals(mpVal)) {
+                                redisVal = mpVal;
+                            }
+                        }
+                    }
+                    if (redisVal == null && StringUtils.isNotBlank(phone)) {
+                        if (baseRedisService.isSetMember("user_sessions:" + phone, token)) {
+                            redisVal = token;
+                        } else {
+                            String userVal = baseRedisService.getString("user_" + phone);
+                            if (StringUtils.isNotBlank(userVal) && token.equals(userVal)) {
+                                redisVal = userVal;
+                            }
                         }
                     }
                 } else {

+ 16 - 2
alien-gateway/src/main/java/shop/alien/gateway/service/LifeUserService.java

@@ -89,7 +89,7 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
 //                userVo.setToken(JWTUtils1.createToken(tokenMap));
                 String token = getToken(phoneNum, userVo.getUserName(), tokenMap);
                 userVo.setToken(token);
-                baseRedisService.setString("user_" + phoneNum, token);
+                addLifeUserSessionToken(phoneNum, token);
                 // 二手平台登录log,同一个macip登录多账号记录
                 addLifeUserLogInfo(user2, macIp);
 
@@ -107,7 +107,7 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
             tokenMap.put("userType", "user");
             String token = getToken(phoneNum, user.getUserName(), tokenMap);
             userVo.setToken(token);
-            baseRedisService.setString("user_" + phoneNum, token);
+            addLifeUserSessionToken(phoneNum, token);
             // 二手平台登录log,同一个macip登录多账号记录
             addLifeUserLogInfo(user, macIp);
 
@@ -141,6 +141,20 @@ public class LifeUserService extends ServiceImpl<LifeUserGatewayMapper, LifeUser
         return token;
     }
 
+    /**
+     * C 端多设备:token 放入 Redis Set;将旧版单 key 迁入 Set 后删除,避免旧 token 长期有效。
+     */
+    private void addLifeUserSessionToken(String phone, String token) {
+        String legacyKey = "user_" + phone;
+        String sessionSetKey = "user_sessions:" + phone;
+        String oldSingle = baseRedisService.getString(legacyKey);
+        if (oldSingle != null && !oldSingle.isEmpty()) {
+            baseRedisService.setSetList(sessionSetKey, oldSingle);
+        }
+        baseRedisService.delete(legacyKey);
+        baseRedisService.setSetList(sessionSetKey, token);
+    }
+
     public LifeUser getUserByPhone(String phoneNum) {
         LambdaQueryWrapper<LifeUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
         lambdaQueryWrapper.eq(LifeUser::getUserPhone, phoneNum);