From d64abaaed31db05bdd6a67267464480bcde68136 Mon Sep 17 00:00:00 2001 From: keke <994305335@qq.com> Date: Mon, 14 Jul 2025 23:39:47 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=9C=B0=E5=9D=80'/system/role/authUser/selectAll',?= =?UTF-8?q?=E5=8F=91=E7=94=9F=E6=9C=AA=E7=9F=A5=E5=BC=82=E5=B8=B8:cn.dev33?= =?UTF-8?q?.satoken.exception.NotWebContextException:=20=E9=9D=9EWeb?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=96=87=E6=97=A0=E6=B3=95=E8=8E=B7=E5=8F=96?= =?UTF-8?q?Request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/ruoyi/system/service/impl/SysRoleServiceImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysRoleServiceImpl.java index b3b24f41..16d329d7 100644 --- a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysRoleServiceImpl.java @@ -439,6 +439,10 @@ public class SysRoleServiceImpl implements ISysRoleService { if (CollUtil.isEmpty(keys)) { return; } + // 修复:请求地址'/system/role/authUser/selectAll',发生未知异常:cn.dev33.satoken.exception.NotWebContextException: 非Web上下文无法获取Request + // 原因:LoginHelper.getLoginUser(); 由于是并行的方式,上下文出现不一致的情况 + // 解决:只需要把用户信息拿到外面来即可 + LoginUser loginUser = LoginHelper.getLoginUser(); // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作 keys.forEach(key -> { String token = StringUtils.substringAfterLast(key, ":"); @@ -447,7 +451,6 @@ public class SysRoleServiceImpl implements ISysRoleService { return; } // LoginUser loginUser = LoginHelper.getLoginUser(token); - LoginUser loginUser = LoginHelper.getLoginUser(); if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) { try { StpUtil.logoutByTokenValue(token); From bc6ed508b0f58295800afcfeb6eeb2cdfdada86d Mon Sep 17 00:00:00 2001 From: keke <994305335@qq.com> Date: Mon, 14 Jul 2025 23:47:47 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A1.=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=8E=9F=E6=9C=AC=E7=BB=91=E5=AE=9A=E4=BA=86=E5=B2=97?= =?UTF-8?q?=E4=BD=8D,=E8=8B=A5=E6=83=B3=E8=A6=81=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=89=80=E6=9C=89=E7=9A=84=E5=B2=97=E4=BD=8D,=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E8=BF=9B=E8=A1=8C=E9=80=BB=E8=BE=91=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=202.=E7=94=A8=E6=88=B7=E5=8E=9F=E6=9C=AC=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E4=BA=86=E8=A7=92=E8=89=B2,=E8=8B=A5=E6=83=B3=E8=A6=81?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E6=89=80=E6=9C=89=E7=9A=84=E8=A7=92=E8=89=B2?= =?UTF-8?q?,=E6=B2=A1=E6=9C=89=E8=BF=9B=E8=A1=8C=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/SysUserServiceImpl.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysUserServiceImpl.java index d5b89de5..1d3aeebd 100644 --- a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -450,11 +450,14 @@ public class SysUserServiceImpl implements ISysUserService, UserService { */ private void insertUserPost(SysUserBo user, boolean clear) { Long[] posts = user.getPostIds(); + // 修复:用户原本绑定了岗位,若想要取消所有的岗位,没有进行逻辑实现 + // 原因:当用户取消所有岗位的时候, 传入的posts是空的,所以不进行操作 + // 解决:先进行清空,后再进行处理逻辑 + if (clear) { + // 删除用户与岗位关联 + userPostMapper.delete(new LambdaQueryWrapper().eq(SysUserPost::getUserId, user.getUserId())); + } if (ArrayUtil.isNotEmpty(posts)) { - if (clear) { - // 删除用户与岗位关联 - userPostMapper.delete(new LambdaQueryWrapper().eq(SysUserPost::getUserId, user.getUserId())); - } // 新增用户与岗位管理 List list = StreamUtils.toList(List.of(posts), postId -> { SysUserPost up = new SysUserPost(); @@ -474,6 +477,13 @@ public class SysUserServiceImpl implements ISysUserService, UserService { * @param clear 清除已存在的关联数据 */ private void insertUserRole(Long userId, Long[] roleIds, boolean clear) { + // 修复:用户原本绑定了角色,若想要取消所有的角色,没有进行逻辑实现 + // 原因:当用户取消所有角色的时候, 传入的roleIds是空的,所以不进行操作 + // 解决:先进行清空,后再进行处理逻辑 + if (clear) { + // 删除用户与角色关联 + userRoleMapper.delete(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userId)); + } if (ArrayUtil.isNotEmpty(roleIds)) { // 判断是否具有此角色的操作权限 List roles = roleMapper.selectRoleList(new LambdaQueryWrapper<>()); @@ -488,10 +498,6 @@ public class SysUserServiceImpl implements ISysUserService, UserService { if (CollUtil.isEmpty(canDoRoleList)) { throw new ServiceException("没有权限访问角色的数据"); } - if (clear) { - // 删除用户与角色关联 - userRoleMapper.delete(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userId)); - } // 新增用户与角色管理 List list = StreamUtils.toList(canDoRoleList, roleId -> { SysUserRole ur = new SysUserRole(); From 9a816bb0c71d72ccb63c1aed20a539019c3f2a4a Mon Sep 17 00:00:00 2001 From: keke <994305335@qq.com> Date: Tue, 15 Jul 2025 00:02:44 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E7=94=A8=E6=88=B7=E3=80=90=E5=A6=82=E6=9E=9C=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E7=BB=91=E5=AE=9A=E4=BB=BB=E4=BD=95=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=E3=80=91=E5=9C=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E7=94=A8=E6=88=B7=E5=88=97=E8=A1=A8=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=20=E8=B0=83=E7=94=A8=20SysUserMappe?= =?UTF-8?q?r=20=E7=9A=84=20selectPageUserList()=20=E6=97=B6=E5=80=99?= =?UTF-8?q?=E6=8A=A5=E9=94=99=EF=BC=9Asql=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/service/impl/SysDataScopeServiceImpl.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDataScopeServiceImpl.java index 925cddb9..cb856915 100644 --- a/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDataScopeServiceImpl.java +++ b/ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDataScopeServiceImpl.java @@ -39,7 +39,17 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService { if (CollUtil.isNotEmpty(list)) { return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId())); } - return null; + // 问题描述: 当前用户【如果没有绑定任何部门的情况下】在查询用户列表分页的时候 调用 SysUserMapper 的 selectPageUserList() 时候报错:sql错误 + // 通过打印sql发现 select count(*) as total from sysUser u left join sys_dept d on u.dept_id where (u.del_flag = ?) and (d.dept_id in ()) + // 在 (d.dept_id in ()) 这个位置报错了, 这个在sql中执行也是不行的 + // 我发现 在 PlusPostInitTableInfoHandler 中的 + // String sql = DataPermissionHelper.ignore(() -> + // parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class) + // ); + // 把这个方法交给框架去处理了, 所以没办法进行判空 + // 于是我找到了这里,想着给这里默认赋值一个 -1 + // 下面的那个 getDeptAndChild 暂时没发现有问题,如果发现问题可以考虑参考这种方法 + return "-1"; } @Override From 21c390c4d68f51d64556c47473713530a2efff61 Mon Sep 17 00:00:00 2001 From: keke <994305335@qq.com> Date: Sat, 2 Aug 2025 13:18:30 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A1.=E5=9C=A8?= =?UTF-8?q?=E4=BD=BF=E7=94=A8dify=E7=9A=84=E6=97=B6=E5=80=99,=E5=8F=91?= =?UTF-8?q?=E9=80=811+1=3D=EF=BC=9F=E6=A8=A1=E5=9E=8B=E8=BF=94=E5=9B=9E2?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E7=AC=AC=E4=BA=8C=E6=AC=A1=E9=97=AE?= =?UTF-8?q?=E4=BB=96=E4=B8=BA=E4=BB=80=E4=B9=88=E7=AD=89=E4=BA=8E2?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C=E6=A8=A1=E5=9E=8B=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=8E=B7=E5=8F=96=E4=B8=8A=E4=B8=8B=E6=96=87=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=8C=E7=BB=8F=E8=BF=87=E6=8E=92=E6=9F=A5=EF=BC=8C?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=E7=BC=BA=E5=B0=91conversationId=EF=BC=8Csess?= =?UTF-8?q?ion=E8=A1=A8=E9=9C=80=E8=A6=81=E6=B7=BB=E5=8A=A0conversationId?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=202.=E5=9C=A8=E4=BD=BF=E7=94=A8dify=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E5=80=99message=E8=A1=A8=E4=B8=AD=E5=B9=B6=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E5=AD=98=E5=82=A8=E6=A8=A1=E5=9E=8B=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84=E6=B6=88=E6=81=AF=EF=BC=8C=E5=B9=B6=E4=B8=94=E6=89=A3?= =?UTF-8?q?=E9=99=A4=E8=B4=B9=E7=94=A8=E3=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/ruoyi/domain/ChatSession.java | 6 ++- .../org/ruoyi/domain/bo/ChatSessionBo.java | 6 ++- .../org/ruoyi/domain/vo/ChatSessionVo.java | 5 +++ .../service/chat/impl/DifyServiceImpl.java | 43 +++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatSession.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatSession.java index aa8967a2..5b37dbc5 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatSession.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatSession.java @@ -1,5 +1,6 @@ package org.ruoyi.domain; +import com.alibaba.excel.annotation.ExcelProperty; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -47,6 +48,9 @@ public class ChatSession extends BaseEntity { * 备注 */ private String remark; - + /** + * 会话id + */ + private String conversationId; } diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatSessionBo.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatSessionBo.java index b47c11ce..d71b0b5f 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatSessionBo.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatSessionBo.java @@ -1,5 +1,6 @@ package org.ruoyi.domain.bo; +import com.alibaba.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -44,6 +45,9 @@ public class ChatSessionBo extends BaseEntity { * 备注 */ private String remark; - + /** + * 会话id + */ + private String conversationId; } diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatSessionVo.java b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatSessionVo.java index fb41319a..9d142591 100644 --- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatSessionVo.java +++ b/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/ChatSessionVo.java @@ -61,6 +61,11 @@ public class ChatSessionVo implements Serializable { @ExcelProperty(value = "创建时间") private String createTime; + /** + * 会话id + */ + @ExcelProperty(value = "会话id") + private String conversationId; } diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DifyServiceImpl.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DifyServiceImpl.java index d609ab98..d9092cc9 100644 --- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DifyServiceImpl.java +++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/DifyServiceImpl.java @@ -1,5 +1,6 @@ package org.ruoyi.chat.service.chat.impl; +import cn.hutool.core.util.StrUtil; import io.github.imfangs.dify.client.DifyClient; import io.github.imfangs.dify.client.DifyClientFactory; import io.github.imfangs.dify.client.callback.ChatStreamCallback; @@ -12,10 +13,15 @@ import io.github.imfangs.dify.client.model.chat.ChatMessage; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.ruoyi.chat.enums.ChatModeType; +import org.ruoyi.chat.service.chat.IChatCostService; import org.ruoyi.chat.service.chat.IChatService; +import org.ruoyi.common.chat.entity.chat.Message; import org.ruoyi.common.chat.request.ChatRequest; +import org.ruoyi.domain.bo.ChatSessionBo; import org.ruoyi.domain.vo.ChatModelVo; +import org.ruoyi.domain.vo.ChatSessionVo; import org.ruoyi.service.IChatModelService; +import org.ruoyi.service.IChatSessionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -31,6 +37,10 @@ public class DifyServiceImpl implements IChatService { @Autowired private IChatModelService chatModelService; + @Autowired + private IChatSessionService chatSessionService; + @Autowired + private IChatCostService chatCostService; @Override public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { @@ -53,6 +63,15 @@ public class DifyServiceImpl implements IChatService { .responseMode(ResponseMode.STREAMING) .build(); + // 获取conversationId + ChatSessionVo sessionInfo = chatSessionService.queryById(chatRequest.getSessionId()); + if (StrUtil.isNotBlank(sessionInfo.getConversationId())) { + message.setConversationId(sessionInfo.getConversationId()); + } + + // 获取模型返回的消息 + StringBuffer respMessage = new StringBuffer(); + // 发送流式消息 try { chatClient.sendChatMessageStream(message, new ChatStreamCallback() { @@ -60,6 +79,7 @@ public class DifyServiceImpl implements IChatService { @Override public void onMessage(MessageEvent event) { emitter.send(event.getAnswer()); + respMessage.append(event.getAnswer()); log.info("收到消息片段: {}", event.getAnswer()); } @@ -67,6 +87,29 @@ public class DifyServiceImpl implements IChatService { public void onMessageEnd(MessageEndEvent event) { emitter.complete(); log.info("消息结束,完整消息ID: {}", event.getMessageId()); + // 更新conversationId + if (StrUtil.isBlank(sessionInfo.getConversationId())) { + String conversationId = event.getConversationId(); + sessionInfo.setConversationId(conversationId); + // 更新conversationId + ChatSessionBo chatSessionBo = new ChatSessionBo(); + chatSessionBo.setConversationId(sessionInfo.getConversationId()); + chatSessionBo.setId(sessionInfo.getId()); + chatSessionBo.setUserId(sessionInfo.getUserId()); + chatSessionBo.setSessionTitle(sessionInfo.getSessionTitle()); + chatSessionBo.setSessionContent(sessionInfo.getSessionContent()); + chatSessionBo.setRemark(sessionInfo.getRemark()); + chatSessionService.updateByBo(chatSessionBo); + } + // 扣除费用 + ChatRequest chatRequestResponse = new ChatRequest(); + // 设置对话角色 + chatRequestResponse.setRole(Message.Role.ASSISTANT.getName()); + chatRequestResponse.setModel(chatRequest.getModel()); + chatRequestResponse.setUserId(chatRequest.getUserId()); + chatRequestResponse.setSessionId(chatRequest.getSessionId()); + chatRequestResponse.setPrompt(respMessage.toString()); + chatCostService.deductToken(chatRequestResponse); } @Override