From 620bb4712a31791231c4381581f0f60088f079fe Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 27 五月 2026 14:03:45 +0800
Subject: [PATCH] Merge branch 'refs/heads/dev_New_pro' into dev_宁夏_英泽防锈

---
 src/main/java/com/ruoyi/ai/context/AiSessionUserContext.java |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/ai/context/AiSessionUserContext.java b/src/main/java/com/ruoyi/ai/context/AiSessionUserContext.java
index 3a5877b..5251561 100644
--- a/src/main/java/com/ruoyi/ai/context/AiSessionUserContext.java
+++ b/src/main/java/com/ruoyi/ai/context/AiSessionUserContext.java
@@ -4,6 +4,8 @@
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -11,18 +13,26 @@
 public class AiSessionUserContext {
 
     private final Map<String, LoginUser> loginUserByMemoryId = new ConcurrentHashMap<>();
+    private final Map<String, Instant> lastAccessTimeByMemoryId = new ConcurrentHashMap<>();
+    private static final Duration SESSION_TIMEOUT = Duration.ofHours(24);
 
     public void bind(String memoryId, LoginUser loginUser) {
         if (!StringUtils.hasText(memoryId) || loginUser == null) {
             return;
         }
         loginUserByMemoryId.put(memoryId, loginUser);
+        lastAccessTimeByMemoryId.put(memoryId, Instant.now());
     }
 
     public LoginUser get(String memoryId) {
         if (!StringUtils.hasText(memoryId)) {
             return null;
         }
+        if (isExpired(memoryId)) {
+            remove(memoryId);
+            return null;
+        }
+        lastAccessTimeByMemoryId.put(memoryId, Instant.now());
         return loginUserByMemoryId.get(memoryId);
     }
 
@@ -31,5 +41,25 @@
             return;
         }
         loginUserByMemoryId.remove(memoryId);
+        lastAccessTimeByMemoryId.remove(memoryId);
+    }
+
+    public void cleanExpiredSessions() {
+        Instant now = Instant.now();
+        lastAccessTimeByMemoryId.entrySet().removeIf(entry -> {
+            boolean expired = Duration.between(entry.getValue(), now).compareTo(SESSION_TIMEOUT) > 0;
+            if (expired) {
+                loginUserByMemoryId.remove(entry.getKey());
+            }
+            return expired;
+        });
+    }
+
+    private boolean isExpired(String memoryId) {
+        Instant lastAccess = lastAccessTimeByMemoryId.get(memoryId);
+        if (lastAccess == null) {
+            return true;
+        }
+        return Duration.between(lastAccess, Instant.now()).compareTo(SESSION_TIMEOUT) > 0;
     }
 }

--
Gitblit v1.9.3