feat: 请求间隔散点图按模型区分颜色

- 后端 get_interval_timeline 接口返回数据添加 model 字段
- 前端散点图按模型分组显示不同颜色的数据点
- 横线统计信息支持按模型分别显示统计数据
- 管理员视图保持按用户分组,用户视图按模型分组
- 更新 mock 数据支持模型字段
This commit is contained in:
fawney19
2025-12-11 21:33:39 +08:00
parent 2dce4102b0
commit 0e8bf0a23b
6 changed files with 199 additions and 46 deletions

View File

@@ -2166,7 +2166,7 @@ function generateIntervalTimelineData(
) {
const now = Date.now()
const startTime = now - hours * 60 * 60 * 1000
const points: Array<{ x: string; y: number; user_id?: string }> = []
const points: Array<{ x: string; y: number; user_id?: string; model?: string }> = []
// 用户列表(用于管理员视图)
const users = [
@@ -2176,6 +2176,14 @@ function generateIntervalTimelineData(
{ id: 'demo-user-uuid-0004', username: 'Bob Zhang' }
]
// 模型列表(用于按模型区分颜色)
const models = [
'claude-sonnet-4-20250514',
'claude-3-5-sonnet-20241022',
'claude-3-5-haiku-20241022',
'claude-opus-4-20250514'
]
// 生成模拟的请求间隔数据
// 间隔时间分布:大部分在 0-10 分钟,少量在 10-60 分钟,极少数在 60-120 分钟
const pointCount = Math.min(limit, Math.floor(hours * 80)) // 每小时约 80 个数据点
@@ -2211,9 +2219,10 @@ function generateIntervalTimelineData(
// 确保间隔不超过 120 分钟
interval = Math.min(interval, 120)
const point: { x: string; y: number; user_id?: string } = {
const point: { x: string; y: number; user_id?: string; model?: string } = {
x: new Date(currentTime).toISOString(),
y: Math.round(interval * 100) / 100
y: Math.round(interval * 100) / 100,
model: models[Math.floor(Math.random() * models.length)]
}
if (includeUserInfo) {
@@ -2231,15 +2240,20 @@ function generateIntervalTimelineData(
// 按时间排序
points.sort((a, b) => new Date(a.x).getTime() - new Date(b.x).getTime())
// 收集出现的模型
const usedModels = [...new Set(points.map(p => p.model).filter(Boolean))] as string[]
const response: {
analysis_period_hours: number
total_points: number
points: typeof points
users?: Record<string, string>
models?: string[]
} = {
analysis_period_hours: hours,
total_points: points.length,
points
points,
models: usedModels
}
if (includeUserInfo) {