feat: 增强管理端工作台用户活跃榜能力
- 新增用户活跃榜接口、筛选与导出能力 - 支持按智能体过滤排行榜并补充前后端测试
This commit is contained in:
@@ -487,15 +487,17 @@ public class ChatAnalyticalDBRepository {
|
||||
* @param startDate 开始日期,包含
|
||||
* @param endDate 结束日期,不包含
|
||||
* @param tenantId 租户 ID,空表示全局
|
||||
* @param assistantId 智能体 ID,空表示全部
|
||||
* @param limit 返回条数
|
||||
* @return 排行列表
|
||||
*/
|
||||
public List<ChatActiveUserRank> queryActiveUserRanks(LocalDate startDate,
|
||||
LocalDate endDate,
|
||||
BigInteger tenantId,
|
||||
int limit) {
|
||||
BigInteger assistantId,
|
||||
Integer limit) {
|
||||
assertAvailable();
|
||||
int safeLimit = Math.max(limit, 1);
|
||||
Integer safeLimit = limit == null ? null : Math.max(limit, 1);
|
||||
List<Object> args = new java.util.ArrayList<>();
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT agg.user_id AS user_id, ")
|
||||
@@ -511,6 +513,10 @@ public class ChatAnalyticalDBRepository {
|
||||
.append("WHERE agg.stat_date >= toDate(?) AND agg.stat_date < toDate(?)");
|
||||
args.add(startDate.toString());
|
||||
args.add(endDate.toString());
|
||||
if (assistantId != null) {
|
||||
sql.append(" AND agg.assistant_id = ?");
|
||||
args.add(assistantId);
|
||||
}
|
||||
appendOptionalTenantFilter(sql, args, tenantId, "s.tenant_id");
|
||||
sql.append(" GROUP BY agg.user_id")
|
||||
.append(") agg ")
|
||||
@@ -520,9 +526,11 @@ public class ChatAnalyticalDBRepository {
|
||||
appendOptionalTenantFilter(sql, args, tenantId, "tenant_id");
|
||||
sql.append(" GROUP BY user_id")
|
||||
.append(") snapshot ON snapshot.user_id = agg.user_id ")
|
||||
.append("ORDER BY agg.session_total DESC, agg.message_total DESC, agg.user_id ASC ")
|
||||
.append("LIMIT ?");
|
||||
args.add(safeLimit);
|
||||
.append("ORDER BY agg.session_total DESC, agg.message_total DESC, agg.user_id ASC ");
|
||||
if (safeLimit != null) {
|
||||
sql.append("LIMIT ?");
|
||||
args.add(safeLimit);
|
||||
}
|
||||
|
||||
return analyticalDBOperations.query(
|
||||
sql.toString(),
|
||||
|
||||
@@ -94,13 +94,15 @@ public interface ChatDashboardQueryService {
|
||||
* @param startDate 开始日期,包含当天
|
||||
* @param endDate 结束日期,不包含当天
|
||||
* @param tenantId 租户 ID,空表示全局
|
||||
* @param assistantId 智能体 ID,空表示全部
|
||||
* @param limit 返回条数
|
||||
* @return 活跃用户排行
|
||||
*/
|
||||
List<ChatActiveUserRank> queryActiveUserRanks(LocalDate startDate,
|
||||
LocalDate endDate,
|
||||
BigInteger tenantId,
|
||||
int limit);
|
||||
BigInteger assistantId,
|
||||
Integer limit);
|
||||
|
||||
/**
|
||||
* 当前分析库是否可用。
|
||||
|
||||
@@ -141,6 +141,7 @@ public class ChatDashboardQueryServiceImpl implements ChatDashboardQueryService
|
||||
* @param startDate 开始日期,包含当天
|
||||
* @param endDate 结束日期,不包含当天
|
||||
* @param tenantId 租户 ID,空表示全局
|
||||
* @param assistantId 智能体 ID,空表示全部
|
||||
* @param limit 返回条数
|
||||
* @return 活跃用户排行
|
||||
*/
|
||||
@@ -148,11 +149,12 @@ public class ChatDashboardQueryServiceImpl implements ChatDashboardQueryService
|
||||
public List<ChatActiveUserRank> queryActiveUserRanks(LocalDate startDate,
|
||||
LocalDate endDate,
|
||||
BigInteger tenantId,
|
||||
int limit) {
|
||||
BigInteger assistantId,
|
||||
Integer limit) {
|
||||
if (!available()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return analyticalDBRepository.queryActiveUserRanks(startDate, endDate, tenantId, limit);
|
||||
return analyticalDBRepository.queryActiveUserRanks(startDate, endDate, tenantId, assistantId, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -104,6 +104,28 @@ public class ChatAnalyticalDBRepositoryTest {
|
||||
Assert.assertTrue(operations.lastQuerySql.contains("(agg.assistant_id IN (?) OR agg.assistant_id IS NULL)"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户活跃榜支持按智能体过滤,且导出场景可不带 limit。
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportAssistantFilterAndUnlimitedUserRanks() {
|
||||
RecordingAnalyticalDBOperations operations = new RecordingAnalyticalDBOperations();
|
||||
|
||||
ChatAnalyticalDBRepository repository = newRepository(operations);
|
||||
repository.queryActiveUserRanks(
|
||||
LocalDate.of(2026, 4, 1),
|
||||
LocalDate.of(2026, 4, 8),
|
||||
BigInteger.ONE,
|
||||
BigInteger.TEN,
|
||||
null
|
||||
);
|
||||
|
||||
Assert.assertNotNull(operations.lastQuerySql);
|
||||
Assert.assertTrue(operations.lastQuerySql.contains("AND agg.assistant_id = ?"));
|
||||
Assert.assertTrue(operations.lastQuerySql.contains("ORDER BY agg.session_total DESC, agg.message_total DESC, agg.user_id ASC"));
|
||||
Assert.assertFalse(operations.lastQuerySql.contains("LIMIT ?"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造仓储实例。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user