v0.1.4-p4
parent
12ce92c6d9
commit
5058599de4
|
|
@ -10,6 +10,7 @@ from services.platform_service import (
|
||||||
build_platform_overview,
|
build_platform_overview,
|
||||||
create_or_update_system_setting,
|
create_or_update_system_setting,
|
||||||
delete_system_setting,
|
delete_system_setting,
|
||||||
|
get_bot_activity_stats,
|
||||||
get_platform_settings,
|
get_platform_settings,
|
||||||
list_system_settings,
|
list_system_settings,
|
||||||
list_activity_events,
|
list_activity_events,
|
||||||
|
|
@ -67,6 +68,11 @@ def get_platform_usage(
|
||||||
return list_usage(session, bot_id=bot_id, limit=limit, offset=offset)
|
return list_usage(session, bot_id=bot_id, limit=limit, offset=offset)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/api/platform/activity-stats")
|
||||||
|
def get_platform_activity_stats(session: Session = Depends(get_session)):
|
||||||
|
return {"items": get_bot_activity_stats(session)}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/platform/events")
|
@router.get("/api/platform/events")
|
||||||
def get_platform_events(bot_id: Optional[str] = None, limit: int = 100, session: Session = Depends(get_session)):
|
def get_platform_events(bot_id: Optional[str] = None, limit: int = 100, session: Session = Depends(get_session)):
|
||||||
return {"items": list_activity_events(session, bot_id=bot_id, limit=limit)}
|
return {"items": list_activity_events(session, bot_id=bot_id, limit=limit)}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from services.platform_activity_service import (
|
from services.platform_activity_service import (
|
||||||
|
get_bot_activity_stats,
|
||||||
list_activity_events,
|
list_activity_events,
|
||||||
prune_expired_activity_events,
|
prune_expired_activity_events,
|
||||||
record_activity_event,
|
record_activity_event,
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export function PlatformAdminDashboardPage({ compactMode }: PlatformAdminDashboa
|
||||||
<PlatformBotActivityAnalyticsSection
|
<PlatformBotActivityAnalyticsSection
|
||||||
isZh={dashboard.isZh}
|
isZh={dashboard.isZh}
|
||||||
activityStats={dashboard.activityStats}
|
activityStats={dashboard.activityStats}
|
||||||
loading={dashboard.loading}
|
loading={dashboard.activityLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
writeCachedPlatformPageSize,
|
writeCachedPlatformPageSize,
|
||||||
} from '../../../utils/platformPageSize';
|
} from '../../../utils/platformPageSize';
|
||||||
import type {
|
import type {
|
||||||
|
BotActivityStatsItem,
|
||||||
PlatformBotResourceSnapshot,
|
PlatformBotResourceSnapshot,
|
||||||
PlatformOverviewResponse,
|
PlatformOverviewResponse,
|
||||||
PlatformSettings,
|
PlatformSettings,
|
||||||
|
|
@ -52,6 +53,8 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
const [resourceError, setResourceError] = useState('');
|
const [resourceError, setResourceError] = useState('');
|
||||||
const [usageData, setUsageData] = useState<PlatformUsageResponse | null>(null);
|
const [usageData, setUsageData] = useState<PlatformUsageResponse | null>(null);
|
||||||
const [usageLoading, setUsageLoading] = useState(false);
|
const [usageLoading, setUsageLoading] = useState(false);
|
||||||
|
const [activityStatsData, setActivityStatsData] = useState<BotActivityStatsItem[] | null>(null);
|
||||||
|
const [activityLoading, setActivityLoading] = useState(false);
|
||||||
const [usagePage, setUsagePage] = useState(1);
|
const [usagePage, setUsagePage] = useState(1);
|
||||||
const [usagePageSize, setUsagePageSize] = useState(() => readCachedPlatformPageSize(10));
|
const [usagePageSize, setUsagePageSize] = useState(() => readCachedPlatformPageSize(10));
|
||||||
const [pageSizeReady, setPageSizeReady] = useState(true);
|
const [pageSizeReady, setPageSizeReady] = useState(true);
|
||||||
|
|
@ -131,6 +134,18 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
}
|
}
|
||||||
}, [isZh, notify, usagePageSize]);
|
}, [isZh, notify, usagePageSize]);
|
||||||
|
|
||||||
|
const loadActivityStats = useCallback(async () => {
|
||||||
|
setActivityLoading(true);
|
||||||
|
try {
|
||||||
|
const res = await axios.get<{ items: BotActivityStatsItem[] }>(`${APP_ENDPOINTS.apiBase}/platform/activity-stats`);
|
||||||
|
setActivityStatsData(Array.isArray(res.data?.items) ? res.data.items : []);
|
||||||
|
} catch (error: any) {
|
||||||
|
notify(error?.response?.data?.detail || (isZh ? '读取 Bot 活跃度统计失败。' : 'Failed to load bot activity analytics.'), { tone: 'error' });
|
||||||
|
} finally {
|
||||||
|
setActivityLoading(false);
|
||||||
|
}
|
||||||
|
}, [isZh, notify]);
|
||||||
|
|
||||||
const loadSelectedBotUsageSummary = useCallback(async (botId: string) => {
|
const loadSelectedBotUsageSummary = useCallback(async (botId: string) => {
|
||||||
if (!botId) {
|
if (!botId) {
|
||||||
setSelectedBotUsageSummary(null);
|
setSelectedBotUsageSummary(null);
|
||||||
|
|
@ -174,6 +189,10 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
void loadUsage(1);
|
void loadUsage(1);
|
||||||
}, [loadUsage, pageSizeReady, usagePageSize]);
|
}, [loadUsage, pageSizeReady, usagePageSize]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void loadActivityStats();
|
||||||
|
}, [loadActivityStats]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setBotListPage(1);
|
setBotListPage(1);
|
||||||
}, [search, botListPageSize]);
|
}, [search, botListPageSize]);
|
||||||
|
|
@ -254,7 +273,7 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
const overviewBots = overview?.summary.bots;
|
const overviewBots = overview?.summary.bots;
|
||||||
const overviewImages = overview?.summary.images;
|
const overviewImages = overview?.summary.images;
|
||||||
const overviewResources = overview?.summary.resources;
|
const overviewResources = overview?.summary.resources;
|
||||||
const activityStats = overview?.activity_stats;
|
const activityStats = activityStatsData || overview?.activity_stats;
|
||||||
const usageSummary = usageData?.summary || overview?.usage.summary;
|
const usageSummary = usageData?.summary || overview?.usage.summary;
|
||||||
const usageAnalytics = usageData?.analytics || overview?.usage.analytics || null;
|
const usageAnalytics = usageData?.analytics || overview?.usage.analytics || null;
|
||||||
|
|
||||||
|
|
@ -283,10 +302,10 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
const usageAnalyticsTicks = useMemo(() => buildPlatformUsageAnalyticsTicks(usageAnalyticsMax), [usageAnalyticsMax]);
|
const usageAnalyticsTicks = useMemo(() => buildPlatformUsageAnalyticsTicks(usageAnalyticsMax), [usageAnalyticsMax]);
|
||||||
|
|
||||||
const refreshAll = useCallback(async () => {
|
const refreshAll = useCallback(async () => {
|
||||||
const jobs: Promise<unknown>[] = [loadOverview(), loadBots(), loadUsage(usagePage)];
|
const jobs: Promise<unknown>[] = [loadOverview(), loadBots(), loadUsage(usagePage), loadActivityStats()];
|
||||||
if (selectedBotId) jobs.push(loadSelectedBotUsageSummary(selectedBotId));
|
if (selectedBotId) jobs.push(loadSelectedBotUsageSummary(selectedBotId));
|
||||||
await Promise.allSettled(jobs);
|
await Promise.allSettled(jobs);
|
||||||
}, [loadBots, loadOverview, loadSelectedBotUsageSummary, loadUsage, selectedBotId, usagePage]);
|
}, [loadActivityStats, loadBots, loadOverview, loadSelectedBotUsageSummary, loadUsage, selectedBotId, usagePage]);
|
||||||
|
|
||||||
const toggleBot = useCallback(async (bot: BotState) => {
|
const toggleBot = useCallback(async (bot: BotState) => {
|
||||||
setOperatingBotId(bot.id);
|
setOperatingBotId(bot.id);
|
||||||
|
|
@ -496,6 +515,7 @@ export function usePlatformDashboard({ compactMode }: UsePlatformDashboardOption
|
||||||
toggleBot,
|
toggleBot,
|
||||||
usageAnalytics,
|
usageAnalytics,
|
||||||
activityStats,
|
activityStats,
|
||||||
|
activityLoading,
|
||||||
usageAnalyticsMax,
|
usageAnalyticsMax,
|
||||||
usageAnalyticsSeries,
|
usageAnalyticsSeries,
|
||||||
usageAnalyticsTicks,
|
usageAnalyticsTicks,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue