回顾

继上一次已经完成的初步探索,本次我将精力主要放在了对于我们这个运维项目的前端开发上。本次项目对于前端界面的要求是不仅要实现运维基本功能的可视化,还要实现智能体的接入。现我已经从监控仪表盘,运维智能体,用户登录等三个模块对前端进行了初步实现。

技术选型与架构概览

核心技术栈

技术领域 选型方案 优势
前端框架 Vue 3 + Composition API 轻量、响应式、生态丰富,组合式 API 提升代码逻辑复用性
构建工具 Vite 极速冷启动、热模块替换
UI组件库 Element Plus 企业级中后台常用组件库,与 Vue 3 深度集成
图标可视化 Vue-echarts 功能强大、文档详尽,支持运维场景所需的折线图、仪表盘等多种图表类型
状态管理 Pinia Vue 官方推荐,轻量
路由管理 Vue Router 4 官方路由方案,支持路由守卫实现权限控制
HTTP客户端 Axios 拦截器机制便于统一处理请求头、错误提示,与后端REST API对接
图标库 Icons-vue 与 Element Plus 配合,提供丰富的常用图

接下来给出核心代码(main.js):

​
import { createApp } from 'vue'
import App from './App.vue'
import router, { setupRouterGuard } from './router'
import { createPinia } from 'pinia'
// Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

// ECharts
import ECharts from 'vue-echarts'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components'

use([CanvasRenderer, LineChart, BarChart, GridComponent, TooltipComponent, LegendComponent, TitleComponent])

const app = createApp(App)
const pinia = createPinia()
app.use(router)
app.use(pinia)
setupRouterGuard(pinia)
// 注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.use(ElementPlus)
app.component('v-chart', ECharts)

app.mount('#app')

​

功能模块

登录界面与主界面

基本实现

在当前实现中,首先用户通过登录页输入账号密码进行登录,然后主界面左侧目录展示不同功能以及账号信息。后续我将在目录中添加更多功能,以及将用户基本信息和权限信息完善。其中,user.js集中管理用户登录状态、Token、用户信息,并提供修改这些状态的方法,同时支持数据持久化;index.js定义应用的页面路由映射,并通过路由守卫实现权限拦截。

二者协同工作的模式:

场景 user.js index.js
用户首次访问网站 从 LocalStorage 读取 token,isLoggedIn 为 false 守卫拦截,跳转到 /login
用户提交登录 调用 setToken,将 token 存入 Store 和 LocalStorage 登录成功后由页面代码执行 router.push('/dashboard')
访问受保护界面 isLoggedIn 返回 true 守卫放行,正常显示页面
用户退出登录 调用 logout 清空状态 执行 router.push('/login') 回到登录页

关键代码

index.js:

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  // State:从 localStorage 初始化,实现持久化
  const token = ref(localStorage.getItem('token') || '')
  const userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'))

  // Getter:判断是否已登录
  const isLoggedIn = computed(() => !!token.value)

  // Actions
  function setToken(newToken) {
    token.value = newToken
    localStorage.setItem('token', newToken)
  }

  function setUserInfo(info) {
    userInfo.value = info
    localStorage.setItem('userInfo', JSON.stringify(info))
  }

  function logout() {
    token.value = ''
    userInfo.value = {}
    localStorage.removeItem('token')
    localStorage.removeItem('userInfo')
  }

  return { token, userInfo, isLoggedIn, setToken, setUserInfo, logout }
})

index.js:

import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/user'
import Dashboard from '@/views/Dashboard.vue'
import Chat from '@/views/Chat.vue'
import Login from '@/views/Login.vue'

const routes = [
  {
    path: '/login',
    name: 'Login',
    component: Login,
    meta: { title: '登录', requiresAuth: false }
  },
  {
    path: '/',
    redirect: '/dashboard',
    meta: { requiresAuth: true }
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: Dashboard,
    meta: { title: '监控仪表盘', requiresAuth: true }
  },
  {
    path: '/chat',
    name: 'Chat',
    component: Chat,
    meta: { title: '运维智能体', requiresAuth: true }
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

// 路由守卫设置函数(需在 main.js 中调用,传入 pinia 实例)
export function setupRouterGuard(pinia) {
  router.beforeEach((to, from) => {
    const userStore = useUserStore(pinia)
    const requiresAuth = to.matched.some(record => record.meta.requiresAuth)

    // 需要认证但未登录 → 返回登录页路径
    if (requiresAuth && !userStore.isLoggedIn) {
      return '/login'
    }
    // 已登录时访问登录页 → 重定向到仪表盘
    if (to.path === '/login' && userStore.isLoggedIn) {
      return '/dashboard'
    }
    // 其他情况正常放行
    return true
  })
}

export default router

效果展示

监控仪表盘

数据概览

顶部统计卡片:在线主机数、平均 CPU、平均内存、活跃告警数。

CPU 使用率折线图(ECharts 渲染)。

主机状态列表表格(含主机名、IP、状态、CPU%、内存%)。

数据来源

通过 src/api/monitor.js 中的 getHostList、getHostMetrics 等函数请求真实后端 API(但是目前仍然使用内置模拟数据用于界面预览)。

效果展示

运维智能体

功能简述

界面布局:

消息列表区域:区分用户消息与助手消息。

输入区域:多行文本框,支持 Ctrl+Enter 发送。

同时预留 sendMessage 方法接入真实 AI 接口(如 /api/chat)以实现智能问答。

效果展示

后续工作

接下来,我将在对界面优化(例如,在本次探索中我了解到运维界面使用深色主题更能防止视觉疲劳和视力损伤)的同时实现更多的运维功能(如查看日志,版本控制,人员详细信息等)。同时我将和团队对接如何接入真实的后端,让项目变得完整统一。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐