feat: rename data metrics to runtime status with more charts

This commit is contained in:
2026-03-21 11:44:38 +08:00
parent b284f395fd
commit 9606d4d9e1
2 changed files with 135 additions and 69 deletions

View File

@@ -16,7 +16,7 @@ const navItems = [
{ name: '任务矩阵', path: '/kanban', icon: LayoutGrid }, { name: '任务矩阵', path: '/kanban', icon: LayoutGrid },
{ name: '任务调度', path: '/todo', icon: CheckSquare }, { name: '任务调度', path: '/todo', icon: CheckSquare },
{ name: '信息交易所', path: '/forum', icon: MessageSquare }, { name: '信息交易所', path: '/forum', icon: MessageSquare },
{ name: '数据舱', path: '/stats', icon: Activity }, { name: '运行状态', path: '/stats', icon: Activity },
{ name: '系统设置', path: '/settings', icon: Settings }, { name: '系统设置', path: '/settings', icon: Settings },
] ]

View File

@@ -89,7 +89,7 @@ const hourlyActivityData = computed(() =>
<template> <template>
<div class="stats-view"> <div class="stats-view">
<div class="stats-header"> <div class="stats-header">
<h1>// DATA METRICS</h1> <h1>// 运行状态</h1>
</div> </div>
<div v-if="isLoading" class="loading-state"> <div v-if="isLoading" class="loading-state">
@@ -136,94 +136,126 @@ const hourlyActivityData = computed(() =>
<!-- CONVERSATIONS --> <!-- CONVERSATIONS -->
<section class="stats-section"> <section class="stats-section">
<SectionHeader title="CONVERSATIONS" tag="cyan" /> <SectionHeader title="沟通系统" tag="cyan" />
<SummaryRow <div class="stats-metrics-row">
v-if="conversationStats" <div class="stat-bar-item">
:items="[ <div class="stat-bar-label">对话数</div>
{ label: 'Total Conversations', value: formatNumber(conversationStats.totals?.conversations || 0) }, <div class="stat-bar-value">{{ formatNumber(conversationStats?.totals?.conversations || 0) }}</div>
{ label: 'Total Messages', value: formatNumber(conversationStats.totals?.messages || 0) }, <div class="stat-bar-chart">
{ label: 'Input Tokens', value: formatNumber(conversationStats.totals?.input_tokens || 0) }, <MiniBarChart v-if="convChartData.length > 0" :data="convChartData.map(d => d.value)" color="var(--accent-cyan)" :height="30" />
{ label: 'Output Tokens', value: formatNumber(conversationStats.totals?.output_tokens || 0) }, </div>
]" </div>
/> <div class="stat-bar-item">
<div class="chart-box" v-if="convChartData.length > 0"> <div class="stat-bar-label">消息数</div>
<div class="chart-label">30-Day Trend</div> <div class="stat-bar-value">{{ formatNumber(conversationStats?.totals?.messages || 0) }}</div>
<MiniLineChart :data="convChartData" color="var(--accent-cyan)" :height="80" /> <div class="stat-bar-chart">
</div> <MiniBarChart v-if="convChartData.length > 0" :data="convChartData.map(d => d.value)" color="var(--accent-purple)" :height="30" />
<div v-else class="empty-state"> </div>
<span>No conversation data yet</span> </div>
<div class="stat-bar-item">
<div class="stat-bar-label">输入Token</div>
<div class="stat-bar-value">{{ formatNumber(conversationStats?.totals?.input_tokens || 0) }}</div>
<div class="stat-bar-chart">
<MiniLineChart v-if="convChartData.length > 0" :data="convChartData" color="var(--accent-amber)" :height="30" />
</div>
</div>
<div class="stat-bar-item">
<div class="stat-bar-label">输出Token</div>
<div class="stat-bar-value">{{ formatNumber(conversationStats?.totals?.output_tokens || 0) }}</div>
<div class="stat-bar-chart">
<MiniLineChart v-if="convChartData.length > 0" :data="convChartData" color="var(--accent-green)" :height="30" />
</div>
</div>
</div> </div>
</section> </section>
<!-- KNOWLEDGE --> <!-- KNOWLEDGE -->
<section class="stats-section"> <section class="stats-section">
<SectionHeader title="KNOWLEDGE BASE" tag="purple" /> <SectionHeader title="知识库" tag="purple" />
<SummaryRow <div class="stats-metrics-row">
v-if="knowledgeStats" <div class="stat-bar-item">
:items="[ <div class="stat-bar-label">新标签</div>
{ label: 'New Tags', value: formatNumber(knowledgeStats.totals?.new_tags || 0) }, <div class="stat-bar-value">{{ formatNumber(knowledgeStats?.totals?.new_tags || 0) }}</div>
{ label: 'Documents', value: formatNumber(knowledgeStats.totals?.documents || 0) }, <div class="stat-bar-chart">
{ label: 'Tag Relations', value: formatNumber(knowledgeStats.totals?.tag_relations || 0) }, <MiniBarChart v-if="knowChartData.length > 0" :data="knowChartData.map(d => d.value)" color="var(--accent-purple)" :height="30" />
]" </div>
:columns="3" </div>
/> <div class="stat-bar-item">
<div class="chart-box" v-if="knowChartData.length > 0"> <div class="stat-bar-label">文档数</div>
<div class="chart-label">Tag Growth</div> <div class="stat-bar-value">{{ formatNumber(knowledgeStats?.totals?.documents || 0) }}</div>
<MiniLineChart :data="knowChartData" color="var(--accent-purple)" :height="80" /> <div class="stat-bar-chart">
</div> <MiniBarChart v-if="knowChartData.length > 0" :data="knowChartData.map(d => d.value)" color="var(--accent-cyan)" :height="30" />
<div v-else class="empty-state"> </div>
<span>No knowledge data yet</span> </div>
<div class="stat-bar-item">
<div class="stat-bar-label">标签关联</div>
<div class="stat-bar-value">{{ formatNumber(knowledgeStats?.totals?.tag_relations || 0) }}</div>
<div class="stat-bar-chart">
<MiniLineChart v-if="knowChartData.length > 0" :data="knowChartData" color="var(--accent-amber)" :height="30" />
</div>
</div>
</div> </div>
</section> </section>
<!-- KANBAN --> <!-- KANBAN -->
<section class="stats-section"> <section class="stats-section">
<SectionHeader title="KANBAN" tag="cyan" /> <SectionHeader title="任务矩阵" tag="cyan" />
<SummaryRow <div class="stats-metrics-row">
v-if="kanbanStats" <div class="stat-bar-item">
:items="[ <div class="stat-bar-label">待处理</div>
{ label: 'Pending Tasks', value: kanbanStats.current_pending_tasks || 0 }, <div class="stat-bar-value">{{ kanbanStats?.current_pending_tasks || 0 }}</div>
{ label: 'New (30d)', value: formatNumber(kanbanStats.totals?.new_tasks || 0) }, <div class="stat-bar-chart">
{ label: 'Done (30d)', value: formatNumber(kanbanStats.totals?.completed_tasks || 0) }, <MiniBarChart :data="kanbanNewData" color="var(--accent-amber)" :height="30" />
]" </div>
:columns="3" </div>
/> <div class="stat-bar-item">
<div class="chart-box" v-if="kanbanNewData.length > 0"> <div class="stat-bar-label">新建(30)</div>
<div class="chart-label">Tasks: New vs Completed</div> <div class="stat-bar-value">{{ formatNumber(kanbanStats?.totals?.new_tasks || 0) }}</div>
<div class="bar-chart-group"> <div class="stat-bar-chart">
<MiniBarChart :data="kanbanNewData" color="var(--accent-cyan)" :height="60" /> <MiniBarChart :data="kanbanNewData" color="var(--accent-cyan)" :height="30" />
<MiniBarChart :data="kanbanDoneData" color="var(--accent-green)" :height="60" /> </div>
</div>
<div class="stat-bar-item">
<div class="stat-bar-label">完成(30)</div>
<div class="stat-bar-value">{{ formatNumber(kanbanStats?.totals?.completed_tasks || 0) }}</div>
<div class="stat-bar-chart">
<MiniBarChart :data="kanbanDoneData" color="var(--accent-green)" :height="30" />
</div>
</div> </div>
</div>
<div v-else class="empty-state">
<span>No kanban data yet</span>
</div> </div>
</section> </section>
<!-- COMMUNITY --> <!-- COMMUNITY -->
<section class="stats-section"> <section class="stats-section">
<SectionHeader title="COMMUNITY" tag="amber" /> <SectionHeader title="信息交易所" tag="amber" />
<SummaryRow <div class="stats-metrics-row">
v-if="communityStats" <div class="stat-bar-item">
:items="[ <div class="stat-bar-label">帖子数</div>
{ label: 'Posts', value: formatNumber(communityStats.totals?.posts || 0) }, <div class="stat-bar-value">{{ formatNumber(communityStats?.totals?.posts || 0) }}</div>
{ label: 'Replies', value: formatNumber(communityStats.totals?.replies || 0) }, <div class="stat-bar-chart">
{ label: 'AI Executions', value: formatNumber(communityStats.totals?.ai_executions || 0) }, <MiniBarChart v-if="communityChartData.length > 0" :data="communityChartData.map(d => d.value)" color="var(--accent-amber)" :height="30" />
]" </div>
:columns="3" </div>
/> <div class="stat-bar-item">
<div class="chart-box" v-if="communityChartData.length > 0"> <div class="stat-bar-label">回复数</div>
<div class="chart-label">Activity Trend</div> <div class="stat-bar-value">{{ formatNumber(communityStats?.totals?.replies || 0) }}</div>
<MiniLineChart :data="communityChartData" color="var(--accent-amber)" :height="80" /> <div class="stat-bar-chart">
</div> <MiniBarChart v-if="communityChartData.length > 0" :data="communityChartData.map(d => d.value)" color="var(--accent-purple)" :height="30" />
<div v-else class="empty-state"> </div>
<span>No community data yet</span> </div>
<div class="stat-bar-item">
<div class="stat-bar-label">AI执行</div>
<div class="stat-bar-value">{{ formatNumber(communityStats?.totals?.ai_executions || 0) }}</div>
<div class="stat-bar-chart">
<MiniLineChart v-if="communityChartData.length > 0" :data="communityChartData" color="var(--accent-cyan)" :height="30" />
</div>
</div>
</div> </div>
</section> </section>
<!-- INSIGHTS --> <!-- INSIGHTS -->
<section class="stats-section"> <section class="stats-section">
<SectionHeader title="PERSONAL INSIGHTS" tag="cyan" /> <SectionHeader title="个人洞察" tag="cyan" />
<div class="insights-grid" v-if="personalInsights"> <div class="insights-grid" v-if="personalInsights">
<div class="insight-card"> <div class="insight-card">
<h4>Hourly Activity</h4> <h4>Hourly Activity</h4>
@@ -292,6 +324,40 @@ const hourlyActivityData = computed(() =>
gap: 8px; gap: 8px;
} }
.stats-metrics-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.stat-bar-item {
background: var(--bg-card);
border: 1px solid var(--border-dim);
border-radius: var(--radius-md);
padding: 16px;
}
.stat-bar-label {
font-family: var(--font-mono);
font-size: 9px;
letter-spacing: 0.1em;
color: var(--text-dim);
text-transform: uppercase;
margin-bottom: 4px;
}
.stat-bar-value {
font-family: var(--font-mono);
font-size: 24px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 8px;
}
.stat-bar-chart {
margin-top: 8px;
}
.stats-section { .stats-section {
background: rgba(10, 15, 26, 0.6); background: rgba(10, 15, 26, 0.6);
border: 1px solid var(--border-dim); border: 1px solid var(--border-dim);