feat(dashboard): add group usage distribution chart to usage page

Add a doughnut chart showing usage statistics broken down by group on
the admin usage records page. The chart appears alongside the existing
model distribution chart (2-column grid), with the token usage trend
chart moved to a separate full-width row below.

Changes:
- backend/pkg/usagestats: add GroupStat type
- backend/service: add GetGroupStatsWithFilters interface method and implementation
- backend/repository: implement GetGroupStatsWithFilters with LEFT JOIN groups
- backend/handler: add GetGroupStats handler with full filter support
- backend/routes: register GET /admin/dashboard/groups route
- backend/tests: add GetGroupStatsWithFilters stubs to contract/sora tests
- frontend/types: add GroupStat interface
- frontend/api: add getGroupStats API function and types
- frontend/components: add GroupDistributionChart.vue doughnut chart
- frontend/views: update UsageView layout and load group stats in parallel
- frontend/i18n: add groupDistribution, group, noGroup keys (zh + en)
This commit is contained in:
erio
2026-03-01 20:10:51 +08:00
parent 2129584fd6
commit 65459a99b6
14 changed files with 379 additions and 6 deletions

View File

@@ -8,6 +8,7 @@ import type {
DashboardStats,
TrendDataPoint,
ModelStat,
GroupStat,
ApiKeyUsageTrendPoint,
UserUsageTrendPoint,
UsageRequestType
@@ -101,6 +102,34 @@ export async function getModelStats(params?: ModelStatsParams): Promise<ModelSta
return data
}
export interface GroupStatsParams {
start_date?: string
end_date?: string
user_id?: number
api_key_id?: number
account_id?: number
group_id?: number
request_type?: UsageRequestType
stream?: boolean
billing_type?: number | null
}
export interface GroupStatsResponse {
groups: GroupStat[]
start_date: string
end_date: string
}
/**
* Get group usage statistics
* @param params - Query parameters for filtering
* @returns Group usage statistics
*/
export async function getGroupStats(params?: GroupStatsParams): Promise<GroupStatsResponse> {
const { data } = await apiClient.get<GroupStatsResponse>('/admin/dashboard/groups', { params })
return data
}
export interface ApiKeyTrendParams extends TrendParams {
limit?: number
}
@@ -203,6 +232,7 @@ export const dashboardAPI = {
getRealtimeMetrics,
getUsageTrend,
getModelStats,
getGroupStats,
getApiKeyUsageTrend,
getUserUsageTrend,
getBatchUsersUsage,