Restore control center copy

This commit is contained in:
2026-06-10 12:17:52 +08:00
parent 8cbace7585
commit b090ecd5f4
@@ -8,7 +8,7 @@ import type {
import type { UserAnnouncement } from '#/api/core/announcement';
import type { Message } from '#/api/core/message';
import { computed, onMounted, reactive, ref } from 'vue';
import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
@@ -39,13 +39,7 @@ import {
} from '@vben/icons';
import { useUserStore } from '@vben/stores';
import {
ElButton,
ElEmpty,
ElProgress,
ElSkeleton,
ElTag,
} from 'element-plus';
import { ElButton, ElEmpty, ElProgress, ElSkeleton, ElTag } from 'element-plus';
import {
getAgentListApi,
@@ -73,6 +67,7 @@ const userStore = useUserStore();
const loading = ref(false);
const loaded = ref(false);
const now = ref(new Date());
const timer = ref<number>();
const agents = ref<AgentListItem[]>([]);
const workflows = ref<WorkflowListItem[]>([]);
const knowledgeBases = ref<KnowledgeBaseListItem[]>([]);
@@ -99,26 +94,26 @@ const displayName = computed(() => {
);
});
const hour = computed(() => now.value.getHours());
const greeting = computed(() => {
if (hour.value < 6) return '凌晨好';
if (hour.value < 12) return '上午好';
if (hour.value < 18) return '午好';
const hour = now.value.getHours();
if (hour < 6) return '凌晨好';
if (hour < 12) return '午好';
if (hour < 18) return '下午好';
return '晚上好';
});
const currentTime = computed(() => {
return now.value.toLocaleTimeString('zh-CN', { hour12: false });
});
const currentTime = computed(() =>
now.value.toLocaleTimeString('zh-CN', { hour12: false }),
);
const currentDate = computed(() => {
return now.value.toLocaleDateString('zh-CN', {
const currentDate = computed(() =>
now.value.toLocaleDateString('zh-CN', {
day: 'numeric',
month: 'long',
weekday: 'long',
year: 'numeric',
});
});
}),
);
const publishedAgents = computed(
() => agents.value.filter((item) => item.status === 'published').length,
@@ -151,7 +146,6 @@ const successRate = computed(() => {
const collaborationItems = computed(() => [
{
color: 'blue',
desc: '发起需求分诊、任务拆解和角色协作',
icon: Send,
path: '/ai-platform/agent',
title: '我发起的',
@@ -159,7 +153,6 @@ const collaborationItems = computed(() => [
},
{
color: 'amber',
desc: '待人工确认、待补充上下文的节点',
icon: ClipboardList,
path: '/ai-platform/workflow-runs',
title: '我的待办',
@@ -167,7 +160,6 @@ const collaborationItems = computed(() => [
},
{
color: 'violet',
desc: '正在运行或最近完成的协作流程',
icon: Workflow,
path: '/ai-platform/workflow-runs',
title: '我的在办',
@@ -175,7 +167,6 @@ const collaborationItems = computed(() => [
},
{
color: 'cyan',
desc: '已沉淀为可复用的智能体能力',
icon: CheckCircle2,
path: '/ai-platform/agent',
title: '我的已办',
@@ -183,7 +174,6 @@ const collaborationItems = computed(() => [
},
{
color: 'orange',
desc: '消息、公告和流程通知',
icon: Bell,
path: '/message/announcement-list',
title: '抄送我的',
@@ -191,7 +181,6 @@ const collaborationItems = computed(() => [
},
{
color: 'green',
desc: '进入编排器创建多 Agent 流程',
icon: Play,
path: '/ai-platform/workflow',
title: '发起流程',
@@ -271,28 +260,24 @@ const quickLinks = [
const resourceCards = computed(() => [
{
desc: `${publishedAgents.value} 个已发布,可参与协作`,
icon: Bot,
label: '智能体',
tone: 'blue',
value: stats.agentTotal,
},
{
desc: `${publishedWorkflows.value} 条已发布,可直接运行`,
icon: Workflow,
label: '流程',
tone: 'cyan',
value: stats.workflowTotal,
},
{
desc: `${knowledgeBases.value.length} 个最近维护`,
icon: BookOpen,
label: '知识库',
tone: 'amber',
value: stats.knowledgeTotal,
},
{
desc: `成功 ${completedRuns.value} / 失败 ${failedRuns.value}`,
icon: Play,
label: '执行记录',
tone: 'green',
@@ -304,6 +289,7 @@ const serverCards = computed(() => {
const overview = serverOverview.value;
const realtime = realtimeStats.value;
const memory = realtime?.memory_details || overview?.memory_info.virtual;
return [
{
desc: `${overview?.cpu_info.total_cores || '-'} 核心`,
@@ -323,9 +309,9 @@ const serverCards = computed(() => {
value: `${Math.round(realtime?.memory_percent ?? overview?.memory_info.virtual.percent ?? 0)}%`,
},
{
desc: `累计 ${formatBytes(overview?.disk_info.total_read_bytes)} / ${formatBytes(overview?.disk_info.total_write_bytes)}`,
desc: `累计读写 ${formatBytes(overview?.disk_info.total_read_bytes)} / ${formatBytes(overview?.disk_info.total_write_bytes)}`,
icon: Server,
label: '磁盘读/写',
label: '磁盘读',
tone: 'amber',
value: `${formatBytes(realtime?.disk_io.read_speed)}/s`,
},
@@ -370,6 +356,7 @@ function getStatusType(status: string) {
async function loadDashboard() {
loading.value = true;
now.value = new Date();
try {
const [
agentRes,
@@ -418,10 +405,14 @@ async function loadDashboard() {
onMounted(() => {
loadDashboard();
window.setInterval(() => {
timer.value = window.setInterval(() => {
now.value = new Date();
}, 1000);
});
onBeforeUnmount(() => {
if (timer.value) window.clearInterval(timer.value);
});
</script>
<template>
@@ -429,10 +420,10 @@ onMounted(() => {
<div class="workbench">
<section class="top-grid">
<div class="welcome-card panel">
<div class="avatar-badge"></div>
<div class="avatar-badge">AI</div>
<div class="welcome-copy">
<h2>{{ greeting }}{{ displayName }}欢迎回来</h2>
<p>今天是个好日子适合让智能体把重复工作接过去</p>
<p>这里汇总智能体流程编排公告消息和服务器状态方便快速进入协作工作</p>
</div>
<div class="time-box">
<strong>{{ currentTime }}</strong>
@@ -440,14 +431,14 @@ onMounted(() => {
</div>
</div>
<div class="weather-card panel">
<div class="panel-title">
<div class="status-card panel">
<div class="panel-title compact">
<CloudSun :size="17" />
<span>今日状态</span>
</div>
<div class="weather-body">
<div class="status-body">
<strong>{{ successRate }}%</strong>
<span> 6 流程完成率</span>
<span>近流程完成率</span>
</div>
</div>
</section>
@@ -540,7 +531,7 @@ onMounted(() => {
<span>{{ formatTime(item.created_at) }} · {{ item.msg_type }}</span>
</button>
</div>
<ElEmpty v-else description="暂无数据" />
<ElEmpty v-else description="暂无消息" />
</div>
</section>
@@ -551,7 +542,7 @@ onMounted(() => {
<small>
{{
serverOverview
? `${serverOverview.basic_info.hostname} (${serverOverview.basic_info.ip_address}) · 运行时间 ${serverOverview.boot_time.uptime_formatted}`
? `${serverOverview.basic_info.hostname} (${serverOverview.basic_info.ip_address}) · 运行 ${serverOverview.boot_time.uptime_formatted}`
: '等待服务器采集数据'
}}
</small>
@@ -577,7 +568,11 @@ onMounted(() => {
<div class="panel-title">
<GitBranch :size="17" />
<span>最近执行</span>
<ElButton link type="primary" @click="go('/ai-platform/workflow-runs')">
<ElButton
link
type="primary"
@click="go('/ai-platform/workflow-runs')"
>
执行历史
</ElButton>
</div>
@@ -667,7 +662,7 @@ onMounted(() => {
</div>
<div class="token-row">
<Calendar :size="17" />
<span> 6 执行消耗 {{ tokenTotal }} tokens</span>
<span>近执行消耗 {{ tokenTotal }} tokens</span>
</div>
</div>
</div>
@@ -716,7 +711,7 @@ onMounted(() => {
color: rgb(248 250 252);
display: flex;
flex-shrink: 0;
font-size: 20px;
font-size: 18px;
font-weight: 700;
height: 50px;
justify-content: center;
@@ -762,20 +757,20 @@ onMounted(() => {
line-height: 1;
}
.weather-card {
.status-card {
display: grid;
gap: 12px;
min-height: 122px;
padding: 18px;
}
.weather-body {
.status-body {
align-items: center;
display: grid;
justify-items: center;
}
.weather-body strong {
.status-body strong {
color: hsl(var(--primary));
font-size: 26px;
line-height: 1;
@@ -800,6 +795,10 @@ onMounted(() => {
padding: 14px 16px 8px;
}
.panel-title.compact {
padding: 0;
}
.panel-title > span {
flex: 1;
font-weight: 650;