mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-03-13 20:53:42 +08:00
Merge pull request #142 from keke-cxn/main
修复:请求地址'/system/role/authUser/selectAll',发生未知异常:cn.dev33.satoken.exce…
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ public class ChatSessionVo implements Serializable {
|
||||
@ExcelProperty(value = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 会话id
|
||||
*/
|
||||
@ExcelProperty(value = "会话id")
|
||||
private String conversationId;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user