-
-
Notifications
You must be signed in to change notification settings - Fork 197
Open
Labels
Description
功能描述
希望增强排行榜的 用户排名 界面,提供两层用户用量洞察能力:
- 展开行:分模型统计 — 在用户排行榜中展开每行,查看该用户按模型维度的用量明细
- 用户统计仪表盘 — 点击用户名,进入该用户的专属统计页面,包含趋势图、模型分布等仪表盘级别的可视化
背景
目前用户排行榜仅展示汇总数据(总请求数、总 Token、总费用)。在多模型混用场景下(claude-sonnet / claude-opus / gemini 等),管理员缺乏以下能力:
- 查看单个用户在不同模型上的消费分布
- 查看单个用户的费用/请求趋势变化
- 对用户的用量模式进行深入分析(哪些模型用得多、缓存命中率如何等)
目前 my-usage 页面已经为普通用户自己提供了类似功能(StatisticsSummaryCard 组件展示请求数/费用/Token/缓存统计 + 分模型明细),但管理员无法从排行榜角度查看任意用户的同等信息。
Part 1: 排行榜展开行 — 分模型统计
需求
在用户排行榜的每一行末尾增加展开按钮,展开后显示该用户按模型维度的统计子表。
预期效果
| 模型 | 请求数 | Token | 费用 |
|---|---|---|---|
| claude-sonnet-4-20250514 | 1,234 | 12.5M | $45.60 |
| claude-opus-4-20250514 | 89 | 2.1M | $28.30 |
| gemini-2.5-pro | 456 | 5.8M | $12.10 |
现有架构支持
usage_ledger表已包含model和original_model字段,可GROUP BY (userId, model)二次聚合LeaderboardTable组件已通过renderExpandedContentprop 支持可展开行(当前用于供应商缓存命中率 Tab)findProviderCacheHitRateLeaderboardWithTimezone已实现"先按父实体聚合 -> 再按模型二次聚合"的模式,可直接参考
建议实现
- 在
src/repository/leaderboard.ts新增UserModelStat接口和二次聚合查询 - 扩展
LeaderboardEntry增加modelStats: UserModelStat[] - 在
leaderboard-view.tsx为scope === "user"添加renderExpandedContent
Part 2: 用户级统计仪表盘
需求
在用户排行榜中,点击用户名可跳转到(或弹出)该用户的专属统计仪表盘,提供与主仪表盘概览页类似的可视化体验,但数据范围限定为该用户。
预期包含的可视化元素
2.1 概览指标卡片
类似 BentoMetricCard 的用户级版本:
- 今日请求数(与昨日同期对比)
- 今日费用(与昨日同期对比)
- 平均响应时间
- 缓存命中率
注:
getOverviewMetricsWithComparison已支持userId参数,可直接复用。
2.2 时间趋势图
类似 StatisticsChartCard 的用户级版本(Recharts AreaChart):
- 费用趋势(按天/小时)
- 请求量趋势(按天/小时)
- 支持 today / 7days / 30days / thisMonth 时间范围切换
- 以该用户的各 API Key 为维度展示多条曲线
注:
getUserStatisticsAction 的底层查询(getKeyStatisticsFromDB)已支持按 userId 过滤,StatisticsChartCard组件可直接复用。
2.3 模型消费分布
类似 my-usage 页面的 StatisticsSummaryCard 中的 Model Breakdown:
- 按模型分组展示:请求数、Token(输入/输出/缓存)、费用、费用占比
- 可点击展开查看 Token 详情(input/output/cache read/cache write)和缓存命中率
注:
getMyStatsSummaryAction 的查询模式可参考,但需改为支持targetUserId参数。
建议实现方案
方案 A: 新页面(推荐)
- 新增路由
/dashboard/leaderboard/user/[userId] - 排行榜用户名变为超链接
- 页面复用现有组件:
BentoMetricCard+StatisticsChartCard+ModelBreakdownColumn
方案 B: 对话框
- 在排行榜行末增加"查看详情"按钮
- 弹出全屏对话框(类似
key-stats-dialog.tsx模式) - 优点:无需离开排行榜页面
相关文件
排行榜(Part 1)
src/repository/leaderboard.ts— 排行榜查询逻辑src/app/[locale]/dashboard/leaderboard/_components/leaderboard-view.tsx— 排行榜 UIsrc/app/[locale]/dashboard/leaderboard/_components/leaderboard-table.tsx— 通用表格(已支持renderExpandedContent)
统计图表(Part 2)
src/app/[locale]/dashboard/_components/bento/statistics-chart-card.tsx— 时间趋势面积图(Recharts AreaChart, 支持 Cost/Calls 切换, Overlay/Stacked 模式)src/app/[locale]/dashboard/_components/bento/metric-card.tsx— 指标卡片组件src/repository/overview.ts—getOverviewMetricsWithComparison(userId?)已支持用户过滤src/actions/statistics.ts—getUserStatistics统计数据源src/repository/statistics.ts— 底层时间序列聚合查询(支持按用户/密钥分组)
参考实现(my-usage 页面)
src/app/[locale]/my-usage/_components/statistics-summary-card.tsx— 用户自有统计卡(含分模型明细,可作为 Part 2.3 参考)src/actions/my-usage.ts—getMyStatsSummary模型级统计查询
数据层
src/drizzle/schema.ts—usage_ledger表(model, original_model, userId, costUsd, tokens 等字段齐全)src/app/api/leaderboard/route.ts— 排行榜 API
环境信息
- CCH 版本:基于 dev 分支最新代码
- 相关 Issue:有没有考虑增加单key但是额度分codex、claude、gemini的功能 #699(per-model quota 需求,方向不同但互补)、feat: 在概览/性能页面展示供应商返回的真实模型名称 #829(展示供应商返回的真实模型名称)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Projects
Status
Backlog