Merge pull request #142 from keke-cxn/main

修复:请求地址'/system/role/authUser/selectAll',发生未知异常:cn.dev33.satoken.exce…
This commit is contained in:
ageerle
2025-08-02 15:56:16 +08:00
committed by GitHub
7 changed files with 87 additions and 12 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -61,6 +61,11 @@ public class ChatSessionVo implements Serializable {
@ExcelProperty(value = "创建时间")
private String createTime;
/**
* 会话id
*/
@ExcelProperty(value = "会话id")
private String conversationId;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
}
if (ArrayUtil.isNotEmpty(posts)) {
if (clear) {
// 删除用户与岗位关联
userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, user.getUserId()));
}
// 新增用户与岗位管理
List<SysUserPost> 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<SysUserRole>().eq(SysUserRole::getUserId, userId));
}
if (ArrayUtil.isNotEmpty(roleIds)) {
// 判断是否具有此角色的操作权限
List<SysRoleVo> 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<SysUserRole>().eq(SysUserRole::getUserId, userId));
}
// 新增用户与角色管理
List<SysUserRole> list = StreamUtils.toList(canDoRoleList, roleId -> {
SysUserRole ur = new SysUserRole();

View File

@@ -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