fix: 完成系统向智能体数据链路切换

- 切换工作台、聊天历史、资源候选与公共调用到 Agent

- 加固资源绑定、删除保护及发布运行并发控制

- 隔离旧 Bot 专属服务和组件并保留兼容入口
This commit is contained in:
2026-07-31 14:24:15 +08:00
parent f0aba1eddd
commit f872eac1f9
114 changed files with 5997 additions and 874 deletions

View File

@@ -21,7 +21,7 @@ import java.math.BigInteger;
@Service
public class ChatHistoryManageServiceImpl implements ChatHistoryManageService {
private static final String ADMIN_ASSISTANT_CODE = "AGENT";
private static final String AGENT_ASSISTANT_CODE = "AGENT";
private final ChatSessionQueryService chatSessionQueryService;
private final ChatSessionCommandService chatSessionCommandService;
@@ -43,24 +43,26 @@ public class ChatHistoryManageServiceImpl implements ChatHistoryManageService {
@Override
public ChatSessionPage queryUserSessions(BigInteger userId, BigInteger assistantId, ChatPageQuery query) {
return chatSessionQueryService.pageSessions(userId, assistantId, query);
return chatSessionQueryService.pageSessions(userId, assistantId, AGENT_ASSISTANT_CODE, query);
}
@Override
public ChatSessionPage queryAdminSessions(ChatSessionFilterQuery query) {
ChatSessionFilterQuery effectiveQuery = query == null ? new ChatSessionFilterQuery() : query;
// 管理端聊天历史已经切换为 Agent 专属入口,类型由服务端固定,避免客户端绕过。
effectiveQuery.setAssistantCode(ADMIN_ASSISTANT_CODE);
effectiveQuery.setAssistantCode(AGENT_ASSISTANT_CODE);
return chatAnalyticalDBRepository.pageSessions(effectiveQuery);
}
@Override
public ChatSessionSummary getUserSession(BigInteger userId, BigInteger sessionId) {
ChatSessionSummary summary = chatSessionQueryService.getSessionSummary(sessionId);
if (summary == null || summary.getIsDeleted() != null && summary.getIsDeleted() == 1) {
throw new BusinessException("会话不存在");
if (summary == null
|| Integer.valueOf(1).equals(summary.getIsDeleted())
|| !AGENT_ASSISTANT_CODE.equals(summary.getAssistantCode())) {
throw new BusinessException("Agent 会话不存在");
}
if (!summary.getUserId().equals(userId)) {
if (summary.getUserId() == null || !summary.getUserId().equals(userId)) {
throw new BusinessException("无权访问该会话");
}
return summary;
@@ -71,7 +73,7 @@ public class ChatHistoryManageServiceImpl implements ChatHistoryManageService {
ChatSessionSummary summary = chatAnalyticalDBRepository.getSession(sessionId);
if (summary == null
|| Integer.valueOf(1).equals(summary.getIsDeleted())
|| !ADMIN_ASSISTANT_CODE.equals(summary.getAssistantCode())) {
|| !AGENT_ASSISTANT_CODE.equals(summary.getAssistantCode())) {
throw new BusinessException("Agent 会话不存在");
}
return summary;

View File

@@ -19,6 +19,7 @@ import tech.easyflow.chatlog.support.ChatJsonSupport;
import tech.easyflow.common.analyticaldb.core.AnalyticalDBOperations;
import tech.easyflow.common.web.exceptions.BusinessException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.math.BigInteger;
@@ -28,6 +29,7 @@ import java.math.BigInteger;
public class ChatHistoryManageServiceImplTest {
private StubChatAnalyticalDBRepository chatAnalyticalDBRepository;
private StubChatSessionQueryHandler chatSessionQueryHandler;
private ChatHistoryManageServiceImpl service;
/**
@@ -35,7 +37,8 @@ public class ChatHistoryManageServiceImplTest {
*/
@Before
public void setUp() {
ChatSessionQueryService chatSessionQueryService = unusedDependency(ChatSessionQueryService.class);
chatSessionQueryHandler = new StubChatSessionQueryHandler();
ChatSessionQueryService chatSessionQueryService = chatSessionQueryHandler.createProxy();
ChatSessionCommandService chatSessionCommandService = unusedDependency(ChatSessionCommandService.class);
ChatHistoryQueryService chatHistoryQueryService = unusedDependency(ChatHistoryQueryService.class);
ChatRoundOperateService chatRoundOperateService = unusedDependency(ChatRoundOperateService.class);
@@ -49,6 +52,56 @@ public class ChatHistoryManageServiceImplTest {
);
}
/**
* 验证用户端列表始终按 Agent 类型查询。
*/
@Test
public void queryUserSessionsShouldForceAgentAssistantCode() {
BigInteger userId = BigInteger.valueOf(2001);
BigInteger agentId = BigInteger.valueOf(3001);
ChatPageQuery query = new ChatPageQuery();
service.queryUserSessions(userId, agentId, query);
Assert.assertEquals(userId, chatSessionQueryHandler.lastUserId);
Assert.assertEquals(agentId, chatSessionQueryHandler.lastAssistantId);
Assert.assertEquals("AGENT", chatSessionQueryHandler.lastAssistantCode);
Assert.assertSame(query, chatSessionQueryHandler.lastPageQuery);
}
/**
* 验证用户端拒绝读取归属于当前用户的旧 Bot 会话。
*/
@Test
public void getUserSessionShouldRejectBotSession() {
BigInteger userId = BigInteger.valueOf(2002);
ChatSessionSummary summary = session(BigInteger.valueOf(3002), "BOT", 0);
summary.setUserId(userId);
chatSessionQueryHandler.sessionResult = summary;
BusinessException exception = Assert.assertThrows(
BusinessException.class,
() -> service.getUserSession(userId, summary.getId())
);
Assert.assertEquals("Agent 会话不存在", exception.getMessage());
}
/**
* 验证用户端可以读取归属于当前用户的 Agent 会话。
*/
@Test
public void getUserSessionShouldReturnOwnedAgentSession() {
BigInteger userId = BigInteger.valueOf(2003);
ChatSessionSummary summary = session(BigInteger.valueOf(3003), "AGENT", 0);
summary.setUserId(userId);
chatSessionQueryHandler.sessionResult = summary;
ChatSessionSummary result = service.getUserSession(userId, summary.getId());
Assert.assertSame(summary, result);
}
/**
* 验证管理端列表始终覆盖客户端传入的会话类型为 Agent。
*/
@@ -197,6 +250,54 @@ public class ChatHistoryManageServiceImplTest {
return summary;
}
/**
* 用户端会话查询依赖桩。
*/
private static class StubChatSessionQueryHandler implements InvocationHandler {
private BigInteger lastUserId;
private BigInteger lastAssistantId;
private String lastAssistantCode;
private ChatPageQuery lastPageQuery;
private ChatSessionSummary sessionResult;
/**
* 创建查询服务代理。
*
* @return 查询服务代理
*/
private ChatSessionQueryService createProxy() {
return (ChatSessionQueryService) Proxy.newProxyInstance(
ChatSessionQueryService.class.getClassLoader(),
new Class<?>[]{ChatSessionQueryService.class},
this
);
}
/**
* 处理测试所需的查询方法。
*
* @param proxy 代理对象
* @param method 被调用方法
* @param args 调用参数
* @return 方法返回值
*/
@Override
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) {
if ("pageSessions".equals(method.getName()) && args != null && args.length == 4) {
lastUserId = (BigInteger) args[0];
lastAssistantId = (BigInteger) args[1];
lastAssistantCode = (String) args[2];
lastPageQuery = (ChatPageQuery) args[3];
return new ChatSessionPage();
}
if ("getSessionSummary".equals(method.getName())) {
return sessionResult;
}
throw new AssertionError("测试路径不应调用查询方法: " + method.getName());
}
}
/**
* 仅记录管理端会话查询参数和返回值的分析库仓储桩。
*/