feat: 增强工作台趋势概览与聊天排行
- 支持用户活跃与智能体活跃趋势统计及自定义时间范围 - 增加用户活跃榜与智能体趋势数据结构及查询实现 - 同步补齐工作台页面展示与定向测试
This commit is contained in:
@@ -2,13 +2,20 @@ package tech.easyflow.admin.service.dashboard.impl;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardAssistantTrendSeriesVo;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardDistributionItemVo;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardOverviewQuery;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardSummaryVo;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardTrendItemVo;
|
||||
import tech.easyflow.admin.model.dashboard.DashboardUserRankItemVo;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatActiveUserRank;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatAssistantSessionTrend;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatAssistantUsageRank;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatDashboardSummary;
|
||||
import tech.easyflow.chatlog.domain.dto.ChatDashboardTrend;
|
||||
import tech.easyflow.chatlog.service.ChatDashboardQueryService;
|
||||
import tech.easyflow.common.entity.LoginAccount;
|
||||
import tech.easyflow.system.service.SysAccountService;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -19,9 +26,13 @@ import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
@@ -56,6 +67,7 @@ public class DashboardServiceImplTest {
|
||||
Assert.assertEquals(summary.getChatMessageTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(summary.getChatSessionTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(summary.getActiveAssistantTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(summary.getChatActiveUserTotal(), Long.valueOf(0L));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,12 +84,19 @@ public class DashboardServiceImplTest {
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00"));
|
||||
when(chatDashboardQueryService.available()).thenReturn(true);
|
||||
when(chatDashboardQueryService.querySummary(any(), any(), any()))
|
||||
.thenReturn(new ChatDashboardSummary(3L, 9L, 1L));
|
||||
.thenReturn(new ChatDashboardSummary(3L, 9L, 1L, 2L));
|
||||
when(chatDashboardQueryService.queryHourlyTrends(any(), any(), any()))
|
||||
.thenReturn(List.of(new ChatDashboardTrend(currentHourKey, 3L, 9L)));
|
||||
.thenReturn(List.of(new ChatDashboardTrend(currentHourKey, 3L, 9L, 2L)));
|
||||
when(chatDashboardQueryService.queryAssistantUsageRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of(new ChatAssistantUsageRank(BigInteger.ONE, "", 3L, 9L)));
|
||||
.thenReturn(List.of(new ChatAssistantUsageRank(BigInteger.ONE, "", 2L, 3L, 9L)));
|
||||
when(chatDashboardQueryService.queryAssistantHourlyTrends(any(), any(), any(), any()))
|
||||
.thenReturn(List.of(new ChatAssistantSessionTrend(BigInteger.ONE, "", currentHourKey, 3L)));
|
||||
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of(new ChatActiveUserRank(BigInteger.valueOf(2), "demo-user", 3L, 9L, 1L)));
|
||||
SysAccountService sysAccountService = mock(SysAccountService.class);
|
||||
when(sysAccountService.resolveDisplayNameMap(any())).thenReturn(Map.of(BigInteger.valueOf(2), "演示用户"));
|
||||
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
|
||||
setField(service, "sysAccountService", sysAccountService);
|
||||
|
||||
Object context = newContext("today", BigInteger.valueOf(9));
|
||||
DashboardSummaryVo summary = new DashboardSummaryVo();
|
||||
@@ -85,7 +104,10 @@ public class DashboardServiceImplTest {
|
||||
|
||||
Object chatStatus = readField(payload, "chatStatus");
|
||||
List<DashboardTrendItemVo> trends = (List<DashboardTrendItemVo>) readField(payload, "trends");
|
||||
List<DashboardAssistantTrendSeriesVo> assistantTrends =
|
||||
(List<DashboardAssistantTrendSeriesVo>) readField(payload, "assistantTrends");
|
||||
List<DashboardDistributionItemVo> distribution = (List<DashboardDistributionItemVo>) readField(payload, "distribution");
|
||||
List<DashboardUserRankItemVo> userRanks = (List<DashboardUserRankItemVo>) readField(payload, "userRanks");
|
||||
|
||||
Assert.assertTrue(Boolean.TRUE.equals(invokeGetter(chatStatus, "getAvailable")));
|
||||
Assert.assertEquals(trends.size(), 24);
|
||||
@@ -94,13 +116,232 @@ public class DashboardServiceImplTest {
|
||||
Assert.assertEquals(trends.get(10).getLabel(), "10:00");
|
||||
Assert.assertEquals(trends.get(10).getChatMessageTotal(), Long.valueOf(9L));
|
||||
Assert.assertEquals(trends.get(10).getChatSessionTotal(), Long.valueOf(3L));
|
||||
Assert.assertEquals(trends.get(10).getActiveUserTotal(), Long.valueOf(2L));
|
||||
Assert.assertEquals(trends.get(11).getChatMessageTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(trends.get(11).getChatSessionTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(summary.getChatMessageTotal(), Long.valueOf(9L));
|
||||
Assert.assertEquals(summary.getChatSessionTotal(), Long.valueOf(3L));
|
||||
Assert.assertEquals(summary.getActiveAssistantTotal(), Long.valueOf(1L));
|
||||
Assert.assertEquals(summary.getChatActiveUserTotal(), Long.valueOf(2L));
|
||||
Assert.assertEquals(assistantTrends.size(), 1);
|
||||
Assert.assertEquals(assistantTrends.get(0).getLabel(), "智能体-1");
|
||||
Assert.assertEquals(assistantTrends.get(0).getTotalSessionCount(), Long.valueOf(3L));
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().size(), 24);
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().get(10).getSessionTotal(), Long.valueOf(3L));
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().get(11).getSessionTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(distribution.get(0).getLabel(), "智能体-1");
|
||||
Assert.assertEquals(distribution.get(0).getAvgMessagePerSession(), Double.valueOf(3D));
|
||||
Assert.assertEquals(distribution.get(0).getAvgSessionPerUser(), Double.valueOf(1.5D));
|
||||
Assert.assertEquals(userRanks.get(0).getLabel(), "演示用户");
|
||||
Assert.assertEquals(userRanks.get(0).getAssistantTotal(), Long.valueOf(1L));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证当系统账号名称仅回退为纯 ID 时,仍优先继续回退到聊天侧账号。
|
||||
*
|
||||
* @throws Exception 反射调用失败
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void shouldFallbackToUserAccountWhenSystemDisplayNameIsOnlyId() throws Exception {
|
||||
DashboardServiceImpl service = new DashboardServiceImpl();
|
||||
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
|
||||
when(chatDashboardQueryService.available()).thenReturn(true);
|
||||
when(chatDashboardQueryService.querySummary(any(), any(), any()))
|
||||
.thenReturn(new ChatDashboardSummary(1L, 1L, 1L, 1L));
|
||||
when(chatDashboardQueryService.queryHourlyTrends(any(), any(), any()))
|
||||
.thenReturn(List.of());
|
||||
when(chatDashboardQueryService.queryAssistantUsageRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of());
|
||||
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of(new ChatActiveUserRank(BigInteger.valueOf(9), "chat-user", 1L, 1L, 1L)));
|
||||
SysAccountService sysAccountService = mock(SysAccountService.class);
|
||||
when(sysAccountService.resolveDisplayNameMap(any())).thenReturn(Map.of(BigInteger.valueOf(9), "9"));
|
||||
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
|
||||
setField(service, "sysAccountService", sysAccountService);
|
||||
|
||||
Object context = newContext("today", BigInteger.ONE);
|
||||
DashboardSummaryVo summary = new DashboardSummaryVo();
|
||||
Object payload = invokeBuildChatPayload(service, context, summary);
|
||||
|
||||
List<DashboardUserRankItemVo> userRanks = (List<DashboardUserRankItemVo>) readField(payload, "userRanks");
|
||||
Assert.assertEquals(userRanks.get(0).getLabel(), "chat-user");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证日趋势会保留 assistantId 为空的排行项,并补齐 7 天点位。
|
||||
*
|
||||
* @throws Exception 反射调用失败
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void shouldBuildDailyAssistantTrendSeriesForRankedAssistants() throws Exception {
|
||||
DashboardServiceImpl service = new DashboardServiceImpl();
|
||||
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
|
||||
when(chatDashboardQueryService.available()).thenReturn(true);
|
||||
when(chatDashboardQueryService.querySummary(any(), any(), any()))
|
||||
.thenReturn(new ChatDashboardSummary(4L, 12L, 2L, 3L));
|
||||
when(chatDashboardQueryService.queryTrends(any(), any(), any()))
|
||||
.thenReturn(List.of());
|
||||
when(chatDashboardQueryService.queryAssistantUsageRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of(
|
||||
new ChatAssistantUsageRank(BigInteger.ONE, "助手-A", 3L, 4L, 12L),
|
||||
new ChatAssistantUsageRank(null, "未知助手", 1L, 2L, 4L)
|
||||
));
|
||||
when(chatDashboardQueryService.queryAssistantTrends(any(), any(), any(), any()))
|
||||
.thenReturn(List.of(
|
||||
new ChatAssistantSessionTrend(BigInteger.ONE, "助手-A", LocalDate.now().minusDays(6).toString(), 2L),
|
||||
new ChatAssistantSessionTrend(BigInteger.ONE, "助手-A", LocalDate.now().toString(), 4L),
|
||||
new ChatAssistantSessionTrend(null, "未知助手", LocalDate.now().minusDays(3).toString(), 2L)
|
||||
));
|
||||
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of());
|
||||
SysAccountService sysAccountService = mock(SysAccountService.class);
|
||||
when(sysAccountService.resolveDisplayNameMap(any())).thenReturn(Map.of());
|
||||
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
|
||||
setField(service, "sysAccountService", sysAccountService);
|
||||
|
||||
Object context = newContext("7d", BigInteger.ONE);
|
||||
DashboardSummaryVo summary = new DashboardSummaryVo();
|
||||
Object payload = invokeBuildChatPayload(service, context, summary);
|
||||
|
||||
List<DashboardAssistantTrendSeriesVo> assistantTrends =
|
||||
(List<DashboardAssistantTrendSeriesVo>) readField(payload, "assistantTrends");
|
||||
Assert.assertEquals(assistantTrends.size(), 2);
|
||||
Assert.assertEquals(assistantTrends.get(0).getLabel(), "助手-A");
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().size(), 7);
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().get(0).getSessionTotal(), Long.valueOf(2L));
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().get(6).getSessionTotal(), Long.valueOf(4L));
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().get(1).getSessionTotal(), Long.valueOf(0L));
|
||||
Assert.assertNull(assistantTrends.get(1).getAssistantId());
|
||||
Assert.assertEquals(assistantTrends.get(1).getLabel(), "未知助手");
|
||||
Assert.assertEquals(assistantTrends.get(1).getPoints().get(3).getSessionTotal(), Long.valueOf(2L));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证自定义单天范围按小时桶构建。
|
||||
*
|
||||
* @throws Exception 反射调用失败
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void shouldBuildHourlyTrendForCustomSingleDayRange() throws Exception {
|
||||
DashboardServiceImpl service = new DashboardServiceImpl();
|
||||
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
|
||||
LocalDate customDate = LocalDate.now().minusDays(2);
|
||||
String currentHourKey = LocalDateTime.of(customDate, LocalTime.of(8, 0))
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00"));
|
||||
when(chatDashboardQueryService.available()).thenReturn(true);
|
||||
when(chatDashboardQueryService.querySummary(any(), any(), any()))
|
||||
.thenReturn(new ChatDashboardSummary(2L, 6L, 1L, 1L));
|
||||
when(chatDashboardQueryService.queryHourlyTrends(any(), any(), any()))
|
||||
.thenReturn(List.of(new ChatDashboardTrend(currentHourKey, 2L, 6L, 1L)));
|
||||
when(chatDashboardQueryService.queryAssistantUsageRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of());
|
||||
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of());
|
||||
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
|
||||
setField(service, "sysAccountService", mock(SysAccountService.class));
|
||||
|
||||
Object context = newContext(
|
||||
"custom",
|
||||
BigInteger.ONE,
|
||||
LocalDateTime.of(customDate, LocalTime.MIN),
|
||||
LocalDateTime.of(customDate.plusDays(1), LocalTime.MIN)
|
||||
);
|
||||
DashboardSummaryVo summary = new DashboardSummaryVo();
|
||||
Object payload = invokeBuildChatPayload(service, context, summary);
|
||||
|
||||
List<DashboardTrendItemVo> trends = (List<DashboardTrendItemVo>) readField(payload, "trends");
|
||||
Assert.assertEquals(trends.size(), 24);
|
||||
Assert.assertEquals(trends.get(8).getKey(), currentHourKey);
|
||||
Assert.assertEquals(trends.get(8).getActiveUserTotal(), Long.valueOf(1L));
|
||||
Assert.assertEquals(trends.get(9).getChatSessionTotal(), Long.valueOf(0L));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证自定义多天范围按天桶构建,并保留查询日期。
|
||||
*
|
||||
* @throws Exception 反射调用失败
|
||||
*/
|
||||
@Test
|
||||
public void shouldBuildDailyBucketsForCustomMultiDayRangeContext() throws Exception {
|
||||
DashboardServiceImpl service = new DashboardServiceImpl();
|
||||
DashboardOverviewQuery query = new DashboardOverviewQuery();
|
||||
query.setRange("custom");
|
||||
query.setStartDate("2026-05-01");
|
||||
query.setEndDate("2026-05-03");
|
||||
|
||||
Object context = invokeBuildContext(service, query);
|
||||
Assert.assertEquals(readField(context, "range"), "custom");
|
||||
Assert.assertEquals(
|
||||
readField(context, "startTime"),
|
||||
LocalDateTime.of(LocalDate.of(2026, 5, 1), LocalTime.MIN)
|
||||
);
|
||||
Assert.assertEquals(
|
||||
readField(context, "endTime"),
|
||||
LocalDateTime.of(LocalDate.of(2026, 5, 4), LocalTime.MIN)
|
||||
);
|
||||
Assert.assertEquals(readField(context, "queryStartDate"), "2026-05-01");
|
||||
Assert.assertEquals(readField(context, "queryEndDate"), "2026-05-03");
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证近 30 天趋势补齐完整 30 个桶,并按 Top 8 请求智能体活跃排行。
|
||||
*
|
||||
* @throws Exception 反射调用失败
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void shouldBuildThirtyDayBucketsAndRequestTopEightAssistantRanks() throws Exception {
|
||||
DashboardServiceImpl service = new DashboardServiceImpl();
|
||||
ChatDashboardQueryService chatDashboardQueryService = mock(ChatDashboardQueryService.class);
|
||||
LocalDate startDate = LocalDate.now().minusDays(29);
|
||||
LocalDate endDate = LocalDate.now();
|
||||
when(chatDashboardQueryService.available()).thenReturn(true);
|
||||
when(chatDashboardQueryService.querySummary(any(), any(), any()))
|
||||
.thenReturn(new ChatDashboardSummary(10L, 20L, 8L, 4L));
|
||||
when(chatDashboardQueryService.queryTrends(any(), any(), any()))
|
||||
.thenReturn(List.of(
|
||||
new ChatDashboardTrend(startDate.toString(), 3L, 6L, 2L),
|
||||
new ChatDashboardTrend(endDate.toString(), 7L, 14L, 4L)
|
||||
));
|
||||
when(chatDashboardQueryService.queryAssistantUsageRanks(any(), any(), any(), eq(8)))
|
||||
.thenReturn(IntStream.rangeClosed(1, 8)
|
||||
.mapToObj(index -> new ChatAssistantUsageRank(
|
||||
BigInteger.valueOf(index),
|
||||
"助手-" + index,
|
||||
index,
|
||||
index * 2L,
|
||||
index * 4L
|
||||
))
|
||||
.toList());
|
||||
when(chatDashboardQueryService.queryAssistantTrends(any(), any(), any(), any()))
|
||||
.thenReturn(List.of(
|
||||
new ChatAssistantSessionTrend(BigInteger.ONE, "助手-1", startDate.toString(), 2L),
|
||||
new ChatAssistantSessionTrend(BigInteger.ONE, "助手-1", endDate.toString(), 4L)
|
||||
));
|
||||
when(chatDashboardQueryService.queryActiveUserRanks(any(), any(), any(), any(Integer.class)))
|
||||
.thenReturn(List.of());
|
||||
setField(service, "chatDashboardQueryService", chatDashboardQueryService);
|
||||
setField(service, "sysAccountService", mock(SysAccountService.class));
|
||||
|
||||
Object context = newContext("30d", BigInteger.ONE);
|
||||
DashboardSummaryVo summary = new DashboardSummaryVo();
|
||||
Object payload = invokeBuildChatPayload(service, context, summary);
|
||||
|
||||
List<DashboardTrendItemVo> trends = (List<DashboardTrendItemVo>) readField(payload, "trends");
|
||||
List<DashboardAssistantTrendSeriesVo> assistantTrends =
|
||||
(List<DashboardAssistantTrendSeriesVo>) readField(payload, "assistantTrends");
|
||||
Assert.assertEquals(trends.size(), 30);
|
||||
Assert.assertEquals(trends.get(0).getKey(), startDate.toString());
|
||||
Assert.assertEquals(trends.get(0).getChatSessionTotal(), Long.valueOf(3L));
|
||||
Assert.assertEquals(trends.get(29).getKey(), endDate.toString());
|
||||
Assert.assertEquals(trends.get(29).getChatMessageTotal(), Long.valueOf(14L));
|
||||
Assert.assertEquals(trends.get(1).getChatSessionTotal(), Long.valueOf(0L));
|
||||
Assert.assertEquals(assistantTrends.size(), 8);
|
||||
Assert.assertEquals(assistantTrends.get(0).getPoints().size(), 30);
|
||||
verify(chatDashboardQueryService).queryAssistantUsageRanks(any(), any(), any(), eq(8));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,6 +353,28 @@ public class DashboardServiceImplTest {
|
||||
* @throws Exception 反射失败
|
||||
*/
|
||||
private Object newContext(String range, BigInteger tenantId) throws Exception {
|
||||
return newContext(
|
||||
range,
|
||||
tenantId,
|
||||
LocalDateTime.of(LocalDate.now(), java.time.LocalTime.MIN),
|
||||
LocalDateTime.of(LocalDate.now().plusDays(1), java.time.LocalTime.MIN)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造查询上下文。
|
||||
*
|
||||
* @param range 时间范围
|
||||
* @param tenantId 租户 ID
|
||||
* @param startTime 开始时间
|
||||
* @param endTime 结束时间
|
||||
* @return 查询上下文实例
|
||||
* @throws Exception 反射失败
|
||||
*/
|
||||
private Object newContext(String range,
|
||||
BigInteger tenantId,
|
||||
LocalDateTime startTime,
|
||||
LocalDateTime endTime) throws Exception {
|
||||
Class<?> contextClass = Class.forName(
|
||||
"tech.easyflow.admin.service.dashboard.impl.DashboardServiceImpl$DashboardQueryContext"
|
||||
);
|
||||
@@ -120,11 +383,29 @@ public class DashboardServiceImplTest {
|
||||
Object context = constructor.newInstance();
|
||||
setField(context, "range", range);
|
||||
setField(context, "tenantFilterId", tenantId);
|
||||
setField(context, "startTime", LocalDateTime.of(LocalDate.now(), java.time.LocalTime.MIN));
|
||||
setField(context, "endTime", LocalDateTime.of(LocalDate.now().plusDays(1), java.time.LocalTime.MIN));
|
||||
setField(context, "startTime", startTime);
|
||||
setField(context, "endTime", endTime);
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用私有上下文构建方法。
|
||||
*
|
||||
* @param service service
|
||||
* @param query 查询参数
|
||||
* @return 上下文
|
||||
* @throws Exception 反射失败
|
||||
*/
|
||||
private Object invokeBuildContext(DashboardServiceImpl service, DashboardOverviewQuery query) throws Exception {
|
||||
Method method = DashboardServiceImpl.class.getDeclaredMethod(
|
||||
"buildContext",
|
||||
LoginAccount.class,
|
||||
DashboardOverviewQuery.class
|
||||
);
|
||||
method.setAccessible(true);
|
||||
return method.invoke(service, null, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用私有聊天载荷组装方法。
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user