From daa7b7315b7123c3402d19333c6ffe2aee5b53e5 Mon Sep 17 00:00:00 2001 From: Yzm Date: Sat, 5 Jul 2025 19:12:33 +0800 Subject: [PATCH] =?UTF-8?q?[fix][feat](chat):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E4=B8=ADSaToken-token=E5=80=BC=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E5=92=8C=E4=BD=BF=E7=94=A8=EF=BC=9B=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E2=80=9C=E8=87=AA=E5=8A=A8=E6=B3=A8=E5=85=A5=E8=AD=A6=E5=91=8A?= =?UTF-8?q?=20=3D>=20=E7=94=A8=E6=88=B7=E6=9C=AA=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 BaseContext 类,用于保存和获取当前登录用户的 token - 在 OpenAIServiceImpl 和 imageServiceImpl 中获取当前会话 token - 将 token 作为参数传递给 SSEEventSourceListener - 在 SSEEventSourceListener 中使用 token 进行用户身份验证和权限控制 - 修改 LoginHelper,增加根据 token 获取登录用户信息的方法 - 更新 InjectionMetaObjectHandler,使用 BaseContext 获取当前 token - 修复对话时出先”自动注入警告 => 用户未登录“ --- .../common/core/service/BaseContext.java | 25 +++++++++++++++++++ .../handler/InjectionMetaObjectHandler.java | 4 ++- .../common/satoken/utils/LoginHelper.java | 14 +++++++++++ .../chat/listener/SSEEventSourceListener.java | 9 ++++++- .../service/chat/impl/ImageServiceImpl.java | 5 +++- .../service/chat/impl/OpenAIServiceImpl.java | 4 ++- 6 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java new file mode 100644 index 00000000..27af6ba0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/service/BaseContext.java @@ -0,0 +1,25 @@ +package org.ruoyi.common.core.service; + +/** + * @description: 基于ThreadLocal封装工具类,用户保存和获取当前登录用户Sa-Token token值 + * @author: yzm + **/ +public class BaseContext { + private static ThreadLocal threadLocal = new ThreadLocal<>(); + + /** + * @description: 设置值 + * @author: yzm + * @param: [token] 线程token + **/ + public static void setCurrentToken(String token){ + threadLocal.set(token); + } + /** + * @description: 获取值 + * @author: yzm + **/ + public static String getCurrentToken(){ + return threadLocal.get(); + } +} \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/InjectionMetaObjectHandler.java index d1b9b8f5..ad908346 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/InjectionMetaObjectHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/InjectionMetaObjectHandler.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.exception.ServiceException; +import org.ruoyi.common.core.service.BaseContext; import org.ruoyi.common.core.utils.ObjectUtils; import org.ruoyi.common.satoken.utils.LoginHelper; import org.ruoyi.core.domain.BaseEntity; @@ -91,7 +92,8 @@ public class InjectionMetaObjectHandler implements MetaObjectHandler { private LoginUser getLoginUser() { LoginUser loginUser; try { - loginUser = LoginHelper.getLoginUser(); + String token = BaseContext.getCurrentToken(); + loginUser = LoginHelper.getLoginUser(token); } catch (Exception e) { log.warn("自动注入警告 => 用户未登录"); return null; diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java index 735a79c4..514e6dba 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java @@ -9,12 +9,16 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; import org.ruoyi.common.core.constant.TenantConstants; import org.ruoyi.common.core.constant.UserConstants; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.enums.DeviceType; import org.ruoyi.common.core.enums.UserType; +import org.ruoyi.common.redis.utils.RedisUtils; +import java.util.Map; import java.util.Set; /** @@ -29,6 +33,7 @@ import java.util.Set; * * @author Lion Li */ +@Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) public class LoginHelper { @@ -82,6 +87,15 @@ public class LoginHelper { return loginUser; } + + public static T getLoginUser(String token) { + SaSession session = StpUtil.getTokenSessionByToken(token); + if (ObjectUtil.isNull(session)) { + return null; + } + return (T) session.get(LOGIN_USER_KEY); + } + /** * 获取用户id */ diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/listener/SSEEventSourceListener.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/listener/SSEEventSourceListener.java index 938a1243..c91e28de 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/listener/SSEEventSourceListener.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/listener/SSEEventSourceListener.java @@ -1,6 +1,7 @@ package org.ruoyi.chat.listener; +import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.collection.CollectionUtil; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; @@ -15,6 +16,7 @@ import org.ruoyi.chat.service.chat.IChatCostService; import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse; import org.ruoyi.common.chat.entity.chat.Message; import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.common.core.service.BaseContext; import org.ruoyi.common.core.utils.SpringUtils; import org.ruoyi.common.core.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -40,11 +42,14 @@ public class SSEEventSourceListener extends EventSourceListener { private Long sessionId; + private String token; + @Autowired(required = false) - public SSEEventSourceListener(SseEmitter emitter,Long userId,Long sessionId) { + public SSEEventSourceListener(SseEmitter emitter,Long userId,Long sessionId, String token) { this.emitter = emitter; this.userId = userId; this.sessionId = sessionId; + this.token = token; } @@ -80,6 +85,8 @@ public class SSEEventSourceListener extends EventSourceListener { chatRequest.setUserId(userId); chatRequest.setSessionId(sessionId); chatRequest.setPrompt(stringBuffer.toString()); + // 记录会话token + BaseContext.setCurrentToken(token); chatCostService.deductToken(chatRequest); return; } diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java index a7eee8e6..709c58ef 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/ImageServiceImpl.java @@ -1,5 +1,6 @@ package org.ruoyi.chat.service.chat.impl; +import cn.dev33.satoken.stp.StpUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.ruoyi.chat.config.ChatConfig; @@ -127,8 +128,10 @@ public class ImageServiceImpl implements IChatService { OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey()); List messages = chatRequest.getMessages(); + // 获取会话token + String token = StpUtil.getTokenValue(); // 创建 SSE 事件源监听器 - SSEEventSourceListener listener = new SSEEventSourceListener(emitter, chatRequest.getUserId(), chatRequest.getSessionId()); + SSEEventSourceListener listener = new SSEEventSourceListener(emitter, chatRequest.getUserId(), chatRequest.getSessionId(), token); // 构建聊天完成请求 ChatCompletion completion = ChatCompletion diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OpenAIServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OpenAIServiceImpl.java index 170dddba..50693617 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OpenAIServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OpenAIServiceImpl.java @@ -1,5 +1,6 @@ package org.ruoyi.chat.service.chat.impl; +import cn.dev33.satoken.stp.StpUtil; import io.modelcontextprotocol.client.McpSyncClient; import lombok.extern.slf4j.Slf4j; import org.ruoyi.chat.config.ChatConfig; @@ -56,7 +57,8 @@ public class OpenAIServiceImpl implements IChatService { Message userMessage = Message.builder().content("工具返回信息:"+toolString).role(Message.Role.USER).build(); messages.add(userMessage); } - SSEEventSourceListener listener = new SSEEventSourceListener(emitter,chatRequest.getUserId(),chatRequest.getSessionId()); + String token = StpUtil.getTokenValue(); + SSEEventSourceListener listener = new SSEEventSourceListener(emitter,chatRequest.getUserId(),chatRequest.getSessionId(), token); ChatCompletion completion = ChatCompletion .builder() .messages(messages)