214 lines
4.7 KiB
Vue
214 lines
4.7 KiB
Vue
<template>
|
||
<div class="dashboard-page">
|
||
<div class="page-header">
|
||
<h1 class="page-title">{{ t('Dashboard') }}</h1>
|
||
</div>
|
||
|
||
<!-- 统计卡片 -->
|
||
<n-grid :cols="4" :x-gap="16" :y-gap="16" :responsive="'screen'" :item-responsive="true" class="stats-grid">
|
||
<!-- 原来的4个统计 -->
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Total Agents')" :value="stats.agents" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Total Nodes')" :value="stats.nodes" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Task Queue')" :value="stats.taskQueue" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Scheduled Tasks')" :value="stats.scheduledTasks" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
|
||
<!-- 新增的5个统计 -->
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Knowledge Base')" :value="stats.knowledgeBase" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Note')" :value="stats.note" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('Event')" :value="stats.event" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('ToDo')" :value="stats.todo" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
<n-grid-item>
|
||
<n-card>
|
||
<n-statistic :label="t('File')" :value="stats.file" />
|
||
</n-card>
|
||
</n-grid-item>
|
||
</n-grid>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { reactive, onMounted } from 'vue'
|
||
import {
|
||
NGrid,
|
||
NGridItem,
|
||
NCard,
|
||
NStatistic
|
||
} from 'naive-ui'
|
||
import { t } from '../shared/i18n'
|
||
import { getCount, getLocalJobCount } from '../shared/api/common'
|
||
|
||
const stats = reactive({
|
||
agents: 0,
|
||
nodes: 0,
|
||
taskQueue: 0,
|
||
scheduledTasks: 0,
|
||
knowledgeBase: 0,
|
||
note: 0,
|
||
event: 0,
|
||
todo: 0,
|
||
file: 0
|
||
})
|
||
|
||
// 加载统计数据
|
||
const loadStats = async () => {
|
||
try {
|
||
// 第一行:原来的4个统计
|
||
// 获取智能体总数
|
||
const agentsResult = await getCount('Local Ai Agent')
|
||
if (agentsResult.success) {
|
||
stats.agents = agentsResult.count || 0
|
||
}
|
||
|
||
// 获取节点总数
|
||
const nodesResult = await getCount('Local Ai Node')
|
||
if (nodesResult.success) {
|
||
stats.nodes = nodesResult.count || 0
|
||
}
|
||
|
||
// 获取任务队列数量 - 使用Local Job (虚拟pagetype,使用专用API)
|
||
const taskQueueResult = await getLocalJobCount()
|
||
if (taskQueueResult.success) {
|
||
stats.taskQueue = taskQueueResult.count || 0
|
||
}
|
||
|
||
// 获取定时任务数量
|
||
const scheduledTasksResult = await getCount('Local Scheduled Job')
|
||
if (scheduledTasksResult.success) {
|
||
stats.scheduledTasks = scheduledTasksResult.count || 0
|
||
}
|
||
|
||
// 第二行:新增的5个统计
|
||
// 获取知识库总数
|
||
const knowledgeBaseResult = await getCount('Knowledge Base')
|
||
if (knowledgeBaseResult.success) {
|
||
stats.knowledgeBase = knowledgeBaseResult.count || 0
|
||
}
|
||
|
||
// 获取笔记总数
|
||
const noteResult = await getCount('Note')
|
||
if (noteResult.success) {
|
||
stats.note = noteResult.count || 0
|
||
}
|
||
|
||
// 获取事件总数
|
||
const eventResult = await getCount('Event')
|
||
if (eventResult.success) {
|
||
stats.event = eventResult.count || 0
|
||
}
|
||
|
||
// 获取待办事项总数
|
||
const todoResult = await getCount('ToDo')
|
||
if (todoResult.success) {
|
||
stats.todo = todoResult.count || 0
|
||
}
|
||
|
||
// 获取文件总数
|
||
const fileResult = await getCount('File')
|
||
if (fileResult.success) {
|
||
stats.file = fileResult.count || 0
|
||
}
|
||
} catch (error) {
|
||
console.error('加载统计数据失败:', error)
|
||
}
|
||
}
|
||
|
||
|
||
onMounted(() => {
|
||
// 加载统计数据
|
||
loadStats()
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.dashboard-page {
|
||
width: 100%;
|
||
padding: 0 16px;
|
||
}
|
||
|
||
.page-header {
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
color: #1f2937;
|
||
margin: 0 0 8px 0;
|
||
}
|
||
|
||
.page-description {
|
||
font-size: 16px;
|
||
color: #6b7280;
|
||
margin: 0;
|
||
}
|
||
|
||
.stats-grid {
|
||
margin-bottom: 24px;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 1200px) {
|
||
.stats-grid {
|
||
--n-grid-cols: 3;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.dashboard-page {
|
||
padding: 0 12px;
|
||
}
|
||
|
||
.stats-grid {
|
||
margin-bottom: 16px;
|
||
--n-grid-cols: 2;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.dashboard-page {
|
||
padding: 0 8px;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.stats-grid {
|
||
--n-grid-cols: 1;
|
||
}
|
||
}
|
||
</style>
|