package com.ruoyi.ai.context; import com.ruoyi.framework.security.LoginUser; 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; @Component public class AiSessionUserContext { private final Map loginUserByMemoryId = new ConcurrentHashMap<>(); private final Map 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); } public void remove(String memoryId) { if (!StringUtils.hasText(memoryId)) { 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; } }