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

@@ -4,8 +4,8 @@ import com.mybatisflex.core.query.QueryWrapper;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import tech.easyflow.ai.entity.Bot;
import tech.easyflow.ai.service.BotService;
import tech.easyflow.agent.entity.Agent;
import tech.easyflow.agent.service.AgentService;
import tech.easyflow.admin.model.dashboard.DashboardAssistantTrendSeriesVo;
import tech.easyflow.admin.model.dashboard.DashboardDistributionItemVo;
import tech.easyflow.admin.model.dashboard.DashboardOverviewQuery;
@@ -22,6 +22,7 @@ import tech.easyflow.chatlog.service.ChatDashboardQueryService;
import tech.easyflow.common.entity.LoginAccount;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.system.entity.SysAccount;
import tech.easyflow.system.enums.CategoryResourceType;
import tech.easyflow.system.service.CategoryPermissionService;
import tech.easyflow.system.service.SysAccountService;
import tech.easyflow.system.service.SysAccountRoleService;
@@ -339,29 +340,34 @@ public class DashboardServiceImplTest {
public void shouldQueryUserRanksWithAssistantFilter() throws Exception {
DashboardServiceImpl service = new DashboardServiceImpl();
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
BotService botService = mock(BotService.class);
AgentService agentService = mock(AgentService.class);
CategoryPermissionService categoryPermissionService = mock(CategoryPermissionService.class);
SysAccountService sysAccountService = mock(SysAccountService.class);
SysAccountRoleService sysAccountRoleService = mock(SysAccountRoleService.class);
SysRoleService sysRoleService = mock(SysRoleService.class);
Bot bot = new Bot();
bot.setId(BigInteger.TEN);
bot.setStatus(1);
bot.setCreatedBy(BigInteger.ONE);
bot.setCategoryId(BigInteger.valueOf(8));
Agent agent = new Agent();
agent.setId(BigInteger.TEN);
agent.setStatus(1);
agent.setCreatedBy(BigInteger.ONE);
agent.setCategoryId(BigInteger.valueOf(8));
when(chatDashboardQueryService.available()).thenReturn(true);
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), eq(BigInteger.TEN), eq(5)))
.thenReturn(List.of(new ChatActiveUserRank(BigInteger.valueOf(2), "demo-user", 2L, 4L, 1L)));
when(botService.getById(BigInteger.TEN)).thenReturn(bot);
when(categoryPermissionService.canAccessCategory(any(LoginAccount.class), eq("BOT"), eq(BigInteger.ONE), eq(BigInteger.valueOf(8))))
when(agentService.getById(BigInteger.TEN)).thenReturn(agent);
when(categoryPermissionService.canAccessCategory(
any(LoginAccount.class),
eq(CategoryResourceType.AGENT.getCode()),
eq(BigInteger.ONE),
eq(BigInteger.valueOf(8))
))
.thenReturn(true);
when(sysAccountService.list(any(QueryWrapper.class))).thenReturn(List.of(buildSysAccount(2L, "demo-user", "演示用户")));
when(sysAccountRoleService.list(any(QueryWrapper.class))).thenReturn(Collections.emptyList());
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
setField(service, "botService", botService);
setField(service, "agentService", agentService);
setField(service, "categoryPermissionService", categoryPermissionService);
setField(service, "sysAccountService", sysAccountService);
setField(service, "sysAccountRoleService", sysAccountRoleService);
@@ -382,26 +388,59 @@ public class DashboardServiceImplTest {
}
/**
* 验证未启用智能体会被拒绝
* 验证用智能体仍可用于筛选历史统计
*/
@Test(expectedExceptions = BusinessException.class, expectedExceptionsMessageRegExp = "聊天助手不存在或未启用")
public void shouldRejectDisabledAssistantFilter() {
@Test
public void shouldAllowDisabledAgentFilterForHistoricalStatistics() {
DashboardServiceImpl service = new DashboardServiceImpl();
BotService botService = mock(BotService.class);
AgentService agentService = mock(AgentService.class);
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
CategoryPermissionService categoryPermissionService = mock(CategoryPermissionService.class);
Bot bot = new Bot();
bot.setId(BigInteger.TEN);
bot.setStatus(0);
Agent agent = new Agent();
agent.setId(BigInteger.TEN);
agent.setStatus(0);
agent.setCreatedBy(BigInteger.ONE);
agent.setCategoryId(BigInteger.valueOf(8));
when(botService.getById(BigInteger.TEN)).thenReturn(bot);
when(agentService.getById(BigInteger.TEN)).thenReturn(agent);
when(chatDashboardQueryService.available()).thenReturn(true);
when(categoryPermissionService.canAccessCategory(
any(LoginAccount.class),
eq(CategoryResourceType.AGENT.getCode()),
eq(BigInteger.ONE),
eq(BigInteger.valueOf(8))
)).thenReturn(true);
setFieldSilently(service, "botService", botService);
setFieldSilently(service, "agentService", agentService);
setFieldSilently(service, "chatDashboardQueryService", chatDashboardQueryService);
setFieldSilently(service, "categoryPermissionService", mock(CategoryPermissionService.class));
setFieldSilently(service, "categoryPermissionService", categoryPermissionService);
setFieldSilently(service, "sysAccountService", mock(SysAccountService.class));
DashboardUserRankQuery query = new DashboardUserRankQuery();
query.setRange("7d");
query.setAssistantId(BigInteger.TEN);
List<DashboardUserRankItemVo> userRanks = service.getUserRanks(new LoginAccount(), query);
Assert.assertTrue(userRanks.isEmpty());
verify(chatDashboardQueryService).queryActiveUserRanks(
any(),
any(),
any(),
eq(BigInteger.TEN),
eq(5)
);
}
/**
* 验证不存在的智能体筛选会被拒绝。
*/
@Test(expectedExceptions = BusinessException.class, expectedExceptionsMessageRegExp = "智能体不存在或不可见")
public void shouldRejectMissingAgentFilter() {
DashboardServiceImpl service = new DashboardServiceImpl();
AgentService agentService = mock(AgentService.class);
setFieldSilently(service, "agentService", agentService);
DashboardUserRankQuery query = new DashboardUserRankQuery();
query.setRange("7d");
query.setAssistantId(BigInteger.TEN);
@@ -411,25 +450,30 @@ public class DashboardServiceImplTest {
/**
* 验证当前作用域不可见的智能体会被拒绝。
*/
@Test(expectedExceptions = BusinessException.class, expectedExceptionsMessageRegExp = "聊天助手不存在或未启用")
@Test(expectedExceptions = BusinessException.class, expectedExceptionsMessageRegExp = "智能体不存在或不可见")
public void shouldRejectInvisibleAssistantFilter() {
DashboardServiceImpl service = new DashboardServiceImpl();
BotService botService = mock(BotService.class);
AgentService agentService = mock(AgentService.class);
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
CategoryPermissionService categoryPermissionService = mock(CategoryPermissionService.class);
Bot bot = new Bot();
bot.setId(BigInteger.TEN);
bot.setStatus(1);
bot.setCreatedBy(BigInteger.ONE);
bot.setCategoryId(BigInteger.valueOf(8));
Agent agent = new Agent();
agent.setId(BigInteger.TEN);
agent.setStatus(1);
agent.setCreatedBy(BigInteger.ONE);
agent.setCategoryId(BigInteger.valueOf(8));
when(botService.getById(BigInteger.TEN)).thenReturn(bot);
when(agentService.getById(BigInteger.TEN)).thenReturn(agent);
when(chatDashboardQueryService.available()).thenReturn(true);
when(categoryPermissionService.canAccessCategory(any(LoginAccount.class), eq("BOT"), eq(BigInteger.ONE), eq(BigInteger.valueOf(8))))
when(categoryPermissionService.canAccessCategory(
any(LoginAccount.class),
eq(CategoryResourceType.AGENT.getCode()),
eq(BigInteger.ONE),
eq(BigInteger.valueOf(8))
))
.thenReturn(false);
setFieldSilently(service, "botService", botService);
setFieldSilently(service, "agentService", agentService);
setFieldSilently(service, "chatDashboardQueryService", chatDashboardQueryService);
setFieldSilently(service, "categoryPermissionService", categoryPermissionService);
setFieldSilently(service, "sysAccountService", mock(SysAccountService.class));