From 2ea903bbcb7e890e1b746722181a8ddf282ad9dc Mon Sep 17 00:00:00 2001 From: "xinxin.wu" Date: Mon, 28 Sep 2026 10:53:23 +0800 Subject: [PATCH] feat: system homepage --- ui/src/api/admin/system/homepage.ts | 74 ++++++++++ .../workspace/application/application.ts | 7 +- ui/src/router/admin/system/index.ts | 2 +- .../home/components/ranking/HomeRankings.vue | 10 +- ui/src/views/system/home/index.vue | 128 ++++++++++++++++++ 5 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 ui/src/api/admin/system/homepage.ts create mode 100644 ui/src/views/system/home/index.vue diff --git a/ui/src/api/admin/system/homepage.ts b/ui/src/api/admin/system/homepage.ts new file mode 100644 index 00000000000..94fd3961a47 --- /dev/null +++ b/ui/src/api/admin/system/homepage.ts @@ -0,0 +1,74 @@ +import { get, getExportFile } from '../core/request' +import type { ParamsPage, ResponsePage } from '../core/types' +import type { + Dict, + HomeApplicationAggregation, + HomeKnowledgeAggregation, + HomeToolAggregation, + HomeModelAggregation, + HomeDateRange, + HomeMonitoringDay, + HomeRankingKind, + HomeRankingRecord, +} from '@/api/types' + +const prefix = `/system/homepage` + +/** 合并系统首页的工作空间筛选条件。 */ +const withWorkspaceId = (workspaceId: string, query: Dict = {}) => ({ + ...query, + workspace_id: workspaceId, +}) +/** 获取智能体数量与发布状态。 */ +const getApplicationAggregation = (workspaceId: string) => + get(`${prefix}/application/aggregation`, withWorkspaceId(workspaceId)) +/** 获取知识库与文档数量。 */ +const getKnowledgeAggregation = (workspaceId: string) => + get(`${prefix}/knowledge/aggregation`, withWorkspaceId(workspaceId)) +/** 获取工具数量与类型分布。 */ +const getToolAggregation = (workspaceId: string) => get(`${prefix}/tool/aggregation`, withWorkspaceId(workspaceId)) +/** 获取模型数量与类型分布。 */ +const getModelAggregation = (workspaceId: string) => get(`${prefix}/model/aggregation`, withWorkspaceId(workspaceId)) +/** 获取指定日期及智能体范围内的每日使用趋势。 */ +const getMonitoring = (workspaceId: string, range: HomeDateRange, applicationId?: string) => + get( + `${prefix}/monitoring/aggregation`, + withWorkspaceId(workspaceId, { + ...range, + ...(applicationId ? { application_id: applicationId } : {}), + }), + ) +/** 获取工作空间日期范围内的 Tokens 总量。 */ +const getTokensAggregation = (workspaceId: string, range: HomeDateRange) => + get(`${prefix}/tokens/aggregation`, withWorkspaceId(workspaceId, { ...range })) +/** 获取工作空间日期范围内的对话轮次。 */ +const getChatRecordAggregation = (workspaceId: string, range: HomeDateRange) => + get(`${prefix}/chat_record/aggregation`, withWorkspaceId(workspaceId, { ...range })) + +const rankingPaths = { tokens: 'tokens_ranking', questions: 'question_ranking', userTokens: 'user_tokens_ranking' } + +/** 分页查询智能体或用户使用排行。 */ +const getRanking = (workspaceId: string, kind: HomeRankingKind, page: ParamsPage, range: HomeDateRange, name?: string) => + get>( + `${prefix}/application/${rankingPaths[kind]}/${page.currentPage}/${page.pageSize}`, + withWorkspaceId(workspaceId, { ...range, ...(name ? { name } : {}) }), + ) +/** 按当前日期与名称筛选导出完整排行。 */ +const exportRanking = (workspaceId: string, kind: HomeRankingKind, range: HomeDateRange, name?: string) => + getExportFile( + `${rankingPaths[kind]}.xlsx`, + `${prefix}/${rankingPaths[kind]}/export`, + withWorkspaceId(workspaceId, { ...range, ...(name ? { name } : {}) }), + ) + +export default { + getApplicationAggregation, + getKnowledgeAggregation, + getToolAggregation, + getModelAggregation, + getMonitoring, + getTokensAggregation, + getChatRecordAggregation, + getRanking, + exportRanking, +} diff --git a/ui/src/api/admin/workspace/application/application.ts b/ui/src/api/admin/workspace/application/application.ts index 6b9ad58522f..5d681b71bf4 100644 --- a/ui/src/api/admin/workspace/application/application.ts +++ b/ui/src/api/admin/workspace/application/application.ts @@ -4,8 +4,7 @@ import type { ApplicationDetail, ApplicationFormPayload, Dict, PromptGeneratePay import { getWorkspaceId } from '@/utils/resource-context' import { ADMIN_API_BASE_PATH } from '@/api/constants' -const getPrefix = () => { - const workspaceId = getWorkspaceId() +const getPrefix = (workspaceId = getWorkspaceId()) => { return `/workspace/${workspaceId}/application` } @@ -17,8 +16,8 @@ const getAllApplication = (query?: Dict) => { } /** 获取工作空间智能体列表。 */ -const getApplicationPage = (page: ParamsPage, query?: Dict) => { - return get>(`${getPrefix()}/${page.currentPage}/${page.pageSize}`, query) +const getApplicationPage = (page: ParamsPage, query?: Dict, workspaceId?: string) => { + return get>(`${getPrefix(workspaceId)}/${page.currentPage}/${page.pageSize}`, query) } /** 获取工作空间智能体详情。 */ diff --git a/ui/src/router/admin/system/index.ts b/ui/src/router/admin/system/index.ts index 8506e2efce9..bee4e18aa48 100644 --- a/ui/src/router/admin/system/index.ts +++ b/ui/src/router/admin/system/index.ts @@ -12,7 +12,7 @@ export const systemRoutes: RouteRecordRaw = { { path: 'home', name: 'system-home', - component: () => import('@/views/system/index.vue'), + component: () => import('@/views/system/home/index.vue'), meta: { title: '首页', activeIcon: 'icon_screen_filled', diff --git a/ui/src/views/home/components/ranking/HomeRankings.vue b/ui/src/views/home/components/ranking/HomeRankings.vue index 9688b0e2be6..b91cde855fa 100644 --- a/ui/src/views/home/components/ranking/HomeRankings.vue +++ b/ui/src/views/home/components/ranking/HomeRankings.vue @@ -101,9 +101,9 @@ onMounted(loadRankings) @detail="handleOpenRanking('tokens')" > - + diff --git a/ui/src/views/system/home/index.vue b/ui/src/views/system/home/index.vue new file mode 100644 index 00000000000..f9f9ddbb39f --- /dev/null +++ b/ui/src/views/system/home/index.vue @@ -0,0 +1,128 @@ + +