diff --git a/server/routers/dashboard_router.py b/server/routers/dashboard_router.py index 0be0d843..5add5cfa 100644 --- a/server/routers/dashboard_router.py +++ b/server/routers/dashboard_router.py @@ -605,7 +605,7 @@ async def get_dashboard_stats( db.query(func.count(Conversation.id)).filter(Conversation.status == "active").scalar() or 0 ) total_messages = db.query(func.count(Message.id)).scalar() or 0 - total_users = db.query(func.count(distinct(Conversation.user_id))).scalar() or 0 + total_users = db.query(func.count(User.id)).scalar() or 0 # Feedback statistics total_feedbacks = db.query(func.count(MessageFeedback.id)).scalar() or 0 @@ -729,19 +729,22 @@ async def get_call_timeseries_stats( if time_range == "7hours": intervals = 7 - start_time = now - timedelta(hours=intervals) + # 包含当前小时:从6小时前开始 + start_time = now - timedelta(hours=intervals-1) time_format = "%Y-%m-%d %H:00" # SQLite compatible approach: 使用datetime函数转换UTC时间为北京时间 group_format = func.strftime("%Y-%m-%d %H:00", func.datetime(Message.created_at, '+8 hours')) elif time_range == "7weeks": intervals = 7 - start_time = now - timedelta(weeks=intervals) + # 包含当前周:从6周前开始 + start_time = now - timedelta(weeks=intervals-1) time_format = "%Y-W%U" # SQLite compatible approach: 使用datetime函数转换UTC时间为北京时间 group_format = func.strftime("%Y-%W", func.datetime(Message.created_at, '+8 hours')) else: # 7days (default) intervals = 7 - start_time = now - timedelta(days=intervals) + # 包含当前天:从6天前开始 + start_time = now - timedelta(days=intervals-1) time_format = "%Y-%m-%d" # SQLite compatible approach: 使用datetime函数转换UTC时间为北京时间 group_format = func.strftime("%Y-%m-%d", func.datetime(Message.created_at, '+8 hours')) @@ -889,7 +892,8 @@ async def get_call_timeseries_stats( # 填充缺失的时间点(使用北京时间) data = [] - current_time = start_time + timedelta(hours=8) # 转换为北京时间 + # 从start_time开始,转换为北京时间 + current_time = start_time + timedelta(hours=8) if time_range == "7hours": delta = timedelta(hours=1) diff --git a/web/src/assets/css/dashboard.css b/web/src/assets/css/dashboard.css index dbd4c168..7b5ea4b6 100644 --- a/web/src/assets/css/dashboard.css +++ b/web/src/assets/css/dashboard.css @@ -493,8 +493,8 @@ .compact-stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); - gap: 16px; - margin-bottom: 24px; + gap: 8px; + margin-bottom: 16px; .mini-stat-card { background-color: var(--gray-0); @@ -629,7 +629,7 @@ @media (max-width: 768px) { .compact-stats-grid { grid-template-columns: repeat(2, 1fr); - gap: 8px; + gap: 6px; .mini-stat-card { padding: 8px; diff --git a/web/src/components/dashboard/CallStatsComponent.vue b/web/src/components/dashboard/CallStatsComponent.vue index e83a9408..a24df3b4 100644 --- a/web/src/components/dashboard/CallStatsComponent.vue +++ b/web/src/components/dashboard/CallStatsComponent.vue @@ -185,8 +185,9 @@ const renderCallStatsChart = () => { let result = `${params[0].name}
` params.forEach(param => { total += param.value + const truncatedName = truncateLegend(param.seriesName) result += `` - result += `${param.seriesName}: ${param.value}
` + result += `${truncatedName}: ${param.value}
` }) const labelMap = { models: '模型调用', agents: '智能体调用', tokens: 'Token消耗', tools: '工具调用' } return `
${labelMap[callDataType.value]}
${result}总计: ${total}` @@ -269,6 +270,7 @@ onUnmounted(() => { flex: 1; display: flex; padding: 16px; /* 减少padding从20px到16px */ + overflow-x: hidden; /* 防止横向滚动条 */ } .call-stats-container {