From 5a9827b862fa8f514609db1b6dae698836953864 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 8 Jun 2026 17:40:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(dashboard):=20=E6=95=B0=E6=8D=AE=E6=80=BB?= =?UTF-8?q?=E8=A7=88=E6=99=BA=E8=83=BD=E4=BD=93=E5=9B=BE=E8=A1=A8=E4=B8=AD?= =?UTF-8?q?=E5=B0=86=E4=BB=A5=20slug=20=E5=B1=95=E7=A4=BA=E7=9A=84?= =?UTF-8?q?=E6=99=BA=E8=83=BD=E4=BD=93ID=E6=9B=BF=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端 AgentAnalytics 和 TimeSeriesStats 响应新增 agent_names 映射字段 - 智体统计图表(对话数/工具调用)x 轴标签替换为智能体名称 - 调用分析堆叠柱状图系列名和图例替换为智能体名称 - 前端新增 resolveAgentName 统一根据映射取名称,不存在则回退到 slug Co-Authored-By: Claude Opus 4.7 --- backend/server/routers/dashboard_router.py | 21 +++++++++++++++++-- .../dashboard/AgentStatsComponent.vue | 10 ++++++--- .../dashboard/CallStatsComponent.vue | 11 ++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/backend/server/routers/dashboard_router.py b/backend/server/routers/dashboard_router.py index c0703a37..82db7072 100644 --- a/backend/server/routers/dashboard_router.py +++ b/backend/server/routers/dashboard_router.py @@ -89,6 +89,7 @@ class AgentAnalytics(BaseModel): agent_satisfaction_rates: list[dict] agent_tool_usage: list[dict] top_performing_agents: list[dict] + agent_names: dict[str, str] = {} # agent_id -> agent_name 映射 class ConversationListItem(BaseModel): @@ -486,7 +487,7 @@ async def get_agent_analytics( ): """获取智能体分析(管理员权限)""" try: - from yuxi.storage.postgres.models_business import Conversation, Message, MessageFeedback, ToolCall + from yuxi.storage.postgres.models_business import Agent, Conversation, Message, MessageFeedback, ToolCall # 获取所有智能体 agents_result = await db.execute( @@ -557,12 +558,19 @@ async def get_agent_analytics( top_performing_agents.sort(key=lambda x: x["conversation_count"], reverse=True) top_performing_agents = top_performing_agents[:5] + agent_slugs = [agent_id for agent_id, _ in agents if agent_id] + agent_names = {} + if agent_slugs: + agent_names_result = await db.execute(select(Agent.slug, Agent.name).where(Agent.slug.in_(agent_slugs))) + agent_names = {slug: name for slug, name in agent_names_result.all()} + return AgentAnalytics( total_agents=total_agents, agent_conversation_counts=agent_conversation_counts, agent_satisfaction_rates=agent_satisfaction, agent_tool_usage=agent_tool_usage, top_performing_agents=top_performing_agents, + agent_names=agent_names, ) except Exception as e: @@ -718,6 +726,7 @@ class TimeSeriesStats(BaseModel): average_count: float peak_count: int peak_date: str + agent_names: dict[str, str] | None = None # agent_id -> agent_name 映射(仅 type=agents) @dashboard.get("/stats/calls/timeseries", response_model=TimeSeriesStats) @@ -729,7 +738,7 @@ async def get_call_timeseries_stats( ): """获取调用分析时间序列统计(管理员权限)""" try: - from yuxi.storage.postgres.models_business import Conversation, Message, ToolCall + from yuxi.storage.postgres.models_business import Agent, Conversation, Message, ToolCall # 计算时间范围(使用北京时间 UTC+8) now = utc_now() @@ -887,6 +896,13 @@ async def get_call_timeseries_stats( categories = sorted(list(categories)) + agent_names = None + if type == "agents" and categories: + agent_slugs = [c for c in categories if c] + if agent_slugs: + result = await db.execute(select(Agent.slug, Agent.name).where(Agent.slug.in_(agent_slugs))) + agent_names = {slug: name for slug, name in result.all()} + # 重新组织数据:按时间点分组每个类别的数据 time_data = {} @@ -961,6 +977,7 @@ async def get_call_timeseries_stats( average_count=average_count, peak_count=peak_data["total"], peak_date=peak_data["date"], + agent_names=agent_names, ) except HTTPException: diff --git a/web/src/components/dashboard/AgentStatsComponent.vue b/web/src/components/dashboard/AgentStatsComponent.vue index 58e6f49f..26188988 100644 --- a/web/src/components/dashboard/AgentStatsComponent.vue +++ b/web/src/components/dashboard/AgentStatsComponent.vue @@ -63,7 +63,7 @@