diff --git a/ALOps_sys_fe/alops-ui/src/permission.js b/ALOps_sys_fe/alops-ui/src/permission.js index e0e32981..8dd24576 100644 --- a/ALOps_sys_fe/alops-ui/src/permission.js +++ b/ALOps_sys_fe/alops-ui/src/permission.js @@ -21,12 +21,8 @@ router.beforeEach((to, from, next) => { to.meta.title && store.dispatch('settings/setTitle', to.meta.title) /* has token*/ if (to.path === '/login') { - // 登录后根据角色重定向到不同主页 - if (store.getters.roles && store.getters.roles.includes('admin')) { - next({ path: '/index_admin' }) - } else { - next({ path: '/' }) - } + // 登录后直接重定向到首页 + next({ path: '/' }) NProgress.done() } else if (isWhiteList(to.path)) { next() @@ -37,11 +33,10 @@ router.beforeEach((to, from, next) => { store.dispatch('user/getInfo').then(() => { isRelogin.show = false store.dispatch('permission/GenerateRoutes').then(accessRoutes => { - // 根据roles权限生成可访问的路由表 - router.addRoutes(accessRoutes) // 动态添加可访问路由表 - // 获取角色信息后,判断是跳转到默认路由还是管理员路由 - const redirectPath = store.getters.roles.includes('admin') ? '/index_admin' : to.path - next({ path: redirectPath, replace: true }) // hack方法 确保addRoutes已完成 + // 动态添加可访问路由表 + router.addRoutes(accessRoutes) + // 统一使用目标路径进行跳转 + next({ path: to.path, replace: true }) // hack方法 确保addRoutes已完成 }) }).catch(err => { store.dispatch('user/LogOut').then(() => { @@ -50,16 +45,7 @@ router.beforeEach((to, from, next) => { }) }) } else { - // 如果访问的是根路径,根据角色重定向 - if (to.path === '/') { - if (store.getters.roles.includes('admin')) { - next({ path: '/index_admin', replace: true }) - } else { - next() - } - } else { - next() - } + next() } } } else { diff --git a/ALOps_sys_fe/alops-ui/src/router/index.js b/ALOps_sys_fe/alops-ui/src/router/index.js index 0b076c27..e37394a6 100644 --- a/ALOps_sys_fe/alops-ui/src/router/index.js +++ b/ALOps_sys_fe/alops-ui/src/router/index.js @@ -30,32 +30,6 @@ import Layout from '@/layout' // 公共路由 export const constantRoutes = [ - { - path: '', - component: Layout, - redirect: 'index', - children: [ - { - path: 'index_admin', - component: () => import('@/views/index'), - name: 'Index', - meta: { title: '首页', icon: 'dashboard', affix: true, roles: ['common'] } - } - ] - }, - // { - // path: '', - // component: Layout, - // redirect: 'index', - // children: [ - // { - // path: 'index_admin', - // component: () => import('@/views/index_1'), - // name: 'IndexAdmin', - // meta: { title: '管理员首页', icon: 'dashboard', affix: true, fullscreen: true } - // } - // ] - // }, { path: '/redirect', component: Layout, @@ -96,7 +70,7 @@ export const constantRoutes = [ path: 'index', component: () => import('@/views/index'), name: 'Index', - meta: { title: '首页', icon: 'dashboard', affix: true, roles: ['common'] } + meta: { title: '首页', icon: 'dashboard', affix: true, fullscreen: true } } ] }, diff --git a/ALOps_sys_fe/alops-ui/src/views/index.vue b/ALOps_sys_fe/alops-ui/src/views/index.vue index a534e48e..7a379bb5 100644 --- a/ALOps_sys_fe/alops-ui/src/views/index.vue +++ b/ALOps_sys_fe/alops-ui/src/views/index.vue @@ -1,546 +1,1895 @@ + currentTime: '', + updateTime: '', + totalDevices: 104, + onlineDevices: 96, + soundAlert: true, + autoSwitch: false, + autoSwitchInterval: null, + showDeviceModal: false, + showRoomModal: false, + showWarningHistory: false, + selectedDevice: {}, + selectedRoom: {}, + historyStartDate: '', + historyEndDate: '', + warningLevelFilter: 'all', + warningStats: { + total: 18, + highLevel: 4, + mediumLevel: 7, + lowLevel: 7 + }, + deviceStatus: [ + { id: 1, name: '一层核心服务器', status: 'normal', value: '98%', type: '服务器', uptime: '156天', cpu: '45%', memory: '62%', network: '125MB/s', temperature: '42°C', lastMaintenance: '2024-09-15' }, + { id: 2, name: '二层数据库集群', status: 'normal', value: '92%', type: '服务器', uptime: '142天', cpu: '38%', memory: '75%', network: '89MB/s', temperature: '45°C', lastMaintenance: '2024-09-20' }, + { id: 3, name: '三层网络交换机', status: 'warning', value: '75%', type: '网络设备', uptime: '89天', cpu: '25%', memory: '48%', network: '210MB/s', temperature: '52°C', lastMaintenance: '2024-08-30' }, + { id: 4, name: '四层防火墙', status: 'normal', value: '88%', type: '安全设备', uptime: '201天', cpu: '18%', memory: '32%', network: '95MB/s', temperature: '38°C', lastMaintenance: '2024-07-15' }, + { id: 5, name: '一层存储设备', status: 'error', value: '45%', type: '存储设备', uptime: '67天', cpu: '62%', memory: '85%', network: '156MB/s', temperature: '58°C', lastMaintenance: '2024-10-05' }, + { id: 6, name: '三层备份系统', status: 'normal', value: '96%', type: '备份设备', uptime: '134天', cpu: '28%', memory: '41%', network: '78MB/s', temperature: '41°C', lastMaintenance: '2024-09-10' }, + { id: 7, name: '二层负载均衡', status: 'warning', value: '68%', type: '网络设备', uptime: '98天', cpu: '52%', memory: '66%', network: '185MB/s', temperature: '49°C', lastMaintenance: '2024-09-25' }, + { id: 8, name: '四层应用服务器', status: 'normal', value: '91%', type: '服务器', uptime: '178天', cpu: '41%', memory: '58%', network: '112MB/s', temperature: '43°C', lastMaintenance: '2024-08-20' } + ], + deviceWarnings: [ + { id: 1, name: '一层存储设备容量不足', level: 'error', time: '10:23', deviceId: 5 }, + { id: 2, name: '三层网络交换机负载高', level: 'warning', time: '09:45', deviceId: 3 }, + { id: 3, name: '二层负载均衡器异常', level: 'warning', time: '09:12', deviceId: 7 }, + { id: 4, name: '二层数据库连接数超限', level: 'error', time: '08:56', deviceId: 2 }, + { id: 5, name: '四层备份任务失败', level: 'warning', time: '08:30', deviceId: 6 }, + { id: 6, name: '一层安全审计异常', level: 'error', time: '07:45', deviceId: 1 } + ], + currentFloor: 1, + floors: [ + { + level: 1, + name: '一层 - 数据中心', + totalDevices: 32, + onlineDevices: 30, + warningDevices: 2, + rooms: [ + { id: 101, name: '服务器机房A', position: { left: 5, top: 10, width: 25, height: 35 } }, + { id: 102, name: '服务器机房B', position: { left: 35, top: 10, width: 25, height: 35 } }, + { id: 103, name: '存储机房', position: { left: 65, top: 10, width: 30, height: 35 } }, + { id: 104, name: '网络设备间', position: { left: 5, top: 50, width: 25, height: 25 } }, + { id: 105, name: 'UPS电源室', position: { left: 35, top: 50, width: 25, height: 25 } }, + { id: 106, name: '空调机房', position: { left: 65, top: 50, width: 30, height: 25 } }, + { id: 107, name: '走廊', position: { left: 0, top: 80, width: 100, height: 15 } } + ], + devices: [ + { id: 101, name: '核心服务器1', status: 'normal', room: '服务器机房A', position: { x: 15, y: 20 }, type: '服务器' }, + { id: 102, name: '核心服务器2', status: 'normal', room: '服务器机房A', position: { x: 15, y: 30 }, type: '服务器' }, + { id: 103, name: '存储阵列A', status: 'warning', room: '存储机房', position: { x: 75, y: 20 }, type: '存储设备' }, + { id: 104, name: '网络交换机', status: 'normal', room: '网络设备间', position: { x: 15, y: 60 }, type: '网络设备' }, + { id: 105, name: '安全审计系统', status: 'error', room: '服务器机房B', position: { x: 45, y: 20 }, type: '安全设备' }, + { id: 106, name: 'UPS电源A', status: 'normal', room: 'UPS电源室', position: { x: 45, y: 60 }, type: '电源设备' }, + { id: 107, name: '备份服务器', status: 'normal', room: '服务器机房B', position: { x: 45, y: 30 }, type: '服务器' }, + { id: 108, name: '数据库集群', status: 'normal', room: '存储机房', position: { x: 75, y: 30 }, type: '服务器' } + ] + }, + { + level: 2, + name: '二层 - 网络中心', + totalDevices: 28, + onlineDevices: 26, + warningDevices: 2, + rooms: [ + { id: 201, name: '核心交换机房', position: { left: 10, top: 10, width: 35, height: 40 } }, + { id: 202, name: '防火墙区域', position: { left: 50, top: 10, width: 40, height: 40 } }, + { id: 203, name: '监控区域', position: { left: 10, top: 55, width: 35, height: 30 } }, + { id: 204, name: '设备维护室', position: { left: 50, top: 55, width: 40, height: 30 } }, + { id: 205, name: '走廊', position: { left: 0, top: 90, width: 100, height: 5 } } + ], + devices: [ + { id: 201, name: '路由器主', status: 'normal', room: '核心交换机房', position: { x: 25, y: 25 }, type: '网络设备' }, + { id: 202, name: '防火墙1', status: 'normal', room: '防火墙区域', position: { x: 65, y: 25 }, type: '安全设备' }, + { id: 203, name: '负载均衡器', status: 'warning', room: '核心交换机房', position: { x: 25, y: 35 }, type: '网络设备' }, + { id: 204, name: 'VPN网关', status: 'normal', room: '防火墙区域', position: { x: 65, y: 35 }, type: '安全设备' }, + { id: 205, name: 'IDS系统', status: 'warning', room: '监控区域', position: { x: 25, y: 70 }, type: '安全设备' }, + { id: 206, name: '网络监控', status: 'normal', room: '监控区域', position: { x: 25, y: 60 }, type: '监控设备' }, + { id: 207, name: '交换机A', status: 'normal', room: '设备维护室', position: { x: 65, y: 70 }, type: '网络设备' }, + { id: 208, name: '交换机B', status: 'normal', room: '设备维护室', position: { x: 75, y: 70 }, type: '网络设备' } + ] + }, + { + level: 3, + name: '三层 - 监控中心', + totalDevices: 24, + onlineDevices: 22, + warningDevices: 2, + rooms: [ + { id: 301, name: '大屏监控区', position: { left: 5, top: 5, width: 60, height: 45 } }, + { id: 302, name: '操作台区域', position: { left: 70, top: 5, width: 25, height: 45 } }, + { id: 303, name: '存储区', position: { left: 5, top: 55, width: 40, height: 35 } }, + { id: 304, name: '设备间', position: { left: 50, top: 55, width: 45, height: 35 } }, + { id: 305, name: '走廊', position: { left: 0, top: 95, width: 100, height: 5 } } + ], + devices: [ + { id: 301, name: '监控服务器', status: 'normal', room: '大屏监控区', position: { x: 30, y: 25 }, type: '服务器' }, + { id: 302, name: '录像设备', status: 'error', room: '存储区', position: { x: 20, y: 70 }, type: '存储设备' }, + { id: 303, name: '分析服务器', status: 'normal', room: '大屏监控区', position: { x: 45, y: 25 }, type: '服务器' }, + { id: 304, name: '报警主机', status: 'normal', room: '操作台区域', position: { x: 80, y: 25 }, type: '安全设备' }, + { id: 305, name: '门禁控制器', status: 'normal', room: '设备间', position: { x: 65, y: 70 }, type: '安防设备' }, + { id: 306, name: '环境监测', status: 'warning', room: '设备间', position: { x: 75, y: 70 }, type: '监控设备' }, + { id: 307, name: '摄像头控制', status: 'normal', room: '操作台区域', position: { x: 80, y: 35 }, type: '安防设备' }, + { id: 308, name: '报警系统', status: 'normal', room: '设备间', position: { x: 65, y: 80 }, type: '安全设备' } + ] + }, + { + level: 4, + name: '四层 - 办公区域', + totalDevices: 20, + onlineDevices: 18, + warningDevices: 2, + rooms: [ + { id: 401, name: '办公区A', position: { left: 5, top: 10, width: 40, height: 35 } }, + { id: 402, name: '办公区B', position: { left: 50, top: 10, width: 45, height: 35 } }, + { id: 403, name: '会议室', position: { left: 5, top: 50, width: 40, height: 35 } }, + { id: 404, name: '打印区', position: { left: 50, top: 50, width: 20, height: 35 } }, + { id: 405, name: '茶水间', position: { left: 75, top: 50, width: 20, height: 35 } }, + { id: 406, name: '走廊', position: { left: 0, top: 90, width: 100, height: 5 } } + ], + devices: [ + { id: 401, name: '办公服务器', status: 'normal', room: '办公区A', position: { x: 25, y: 25 }, type: '服务器' }, + { id: 402, name: '打印机', status: 'warning', room: '打印区', position: { x: 60, y: 65 }, type: '办公设备' }, + { id: 403, name: '网络终端', status: 'normal', room: '办公区B', position: { x: 70, y: 25 }, type: '网络设备' }, + { id: 404, name: '视频会议', status: 'normal', room: '会议室', position: { x: 25, y: 65 }, type: '会议设备' }, + { id: 405, name: '电话系统', status: 'warning', room: '办公区A', position: { x: 25, y: 35 }, type: '通信设备' }, + { id: 406, name: '考勤系统', status: 'normal', room: '办公区B', position: { x: 70, y: 35 }, type: '安防设备' }, + { id: 407, name: '门禁系统', status: 'normal', room: '走廊', position: { x: 50, y: 92 }, type: '安防设备' }, + { id: 408, name: '投影设备', status: 'normal', room: '会议室', position: { x: 25, y: 55 }, type: '会议设备' } + ] + } + ], + dataFlows: [], + barChart: null, + pieChart: null, + historyChart: null, + highlightedDevice: null + }}, + computed: { + filteredDeviceStatus() { + if (this.warningLevelFilter === 'all') { + return this.deviceStatus; + } + return this.deviceStatus.filter(device => device.status === this.warningLevelFilter); + }, + filteredWarnings() { + if (this.warningLevelFilter === 'all') { + return this.deviceWarnings; + } + return this.deviceWarnings.filter(warning => + (this.warningLevelFilter === 'error' && warning.level === 'error') || + (this.warningLevelFilter === 'warning' && warning.level === 'warning') + ); + } + }, + mounted() { + this.updateTimeDisplay(); + setInterval(this.updateTimeDisplay, 1000); + + // 初始化日期 + const today = new Date(); + this.historyEndDate = today.toISOString().split('T')[0]; + const oneWeekAgo = new Date(today); + oneWeekAgo.setDate(today.getDate() - 7); + this.historyStartDate = oneWeekAgo.toISOString().split('T')[0]; + + this.generateDataFlows(); + + // 使用nextTick确保DOM已完全渲染 + this.$nextTick(() => { + this.initBarChart(); + this.initPieChart(); + }); + + // 监听窗口大小变化 + window.addEventListener('resize', this.handleResize); + + // 模拟数据更新 + setInterval(this.updateData, 5000); + + // 模拟WebSocket连接 + this.simulateWebSocket(); + }, + beforeDestroy() { + // 移除事件监听 + window.removeEventListener('resize', this.handleResize); + if (this.autoSwitchInterval) { + clearInterval(this.autoSwitchInterval); + } + }, + methods: { + updateTimeDisplay() { + const now = new Date(); + this.currentTime = now.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + hour12: false + }); + + if (!this.updateTime) { + this.updateTime = this.currentTime; + } + }, + + initBarChart() { + this.barChart = echarts.init(this.$refs.chart); + + const option = { + backgroundColor: 'transparent', + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, + legend: { + data: ['正常设备', '预警设备', '故障设备'], + textStyle: { + color: '#a0aec0' + }, + top: 10 + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'category', + data: ['服务器', '网络设备', '存储设备', '安全设备', '备份设备'], + axisLine: { + lineStyle: { + color: '#4dabff' + } + }, + axisLabel: { + color: '#a0aec0' + } + }, + yAxis: { + type: 'value', + axisLine: { + lineStyle: { + color: '#4dabff' + } + }, + axisLabel: { + color: '#a0aec0' + }, + splitLine: { + lineStyle: { + color: 'rgba(77, 171, 255, 0.2)' + } + } + }, + series: [ + { + name: '正常设备', + type: 'bar', + stack: 'total', + emphasis: { + focus: 'series' + }, + data: [32, 28, 15, 12, 8], + itemStyle: { + color: '#4CAF50' + } + }, + { + name: '预警设备', + type: 'bar', + stack: 'total', + emphasis: { + focus: 'series' + }, + data: [5, 7, 3, 2, 1], + itemStyle: { + color: '#FF9800' + } + }, + { + name: '故障设备', + type: 'bar', + stack: 'total', + emphasis: { + focus: 'series' + }, + data: [2, 1, 1, 0, 0], + itemStyle: { + color: '#F44336' + } + } + ] + }; + + this.barChart.setOption(option); + }, + + initPieChart() { + this.pieChart = echarts.init(this.$refs.pieChart); + + const option = { + backgroundColor: 'transparent', + tooltip: { + trigger: 'item', + formatter: '{a}
{b}: {c} ({d}%)' + }, + legend: { + orient: 'vertical', + right: 10, + top: 'center', + textStyle: { + color: '#a0aec0' + } + }, + series: [ + { + name: '设备类型', + type: 'pie', + radius: ['40%', '70%'], + avoidLabelOverlap: false, + itemStyle: { + borderRadius: 10, + borderColor: '#0a1633', + borderWidth: 2 + }, + label: { + show: false, + position: 'center' + }, + emphasis: { + label: { + show: true, + fontSize: '18', + fontWeight: 'bold', + color: '#62f7ff' + } + }, + labelLine: { + show: false + }, + data: [ + { value: 35, name: '服务器', itemStyle: { color: '#4dabff' } }, + { value: 25, name: '网络设备', itemStyle: { color: '#62f7ff' } }, + { value: 18, name: '存储设备', itemStyle: { color: '#ffa726' } }, + { value: 15, name: '安全设备', itemStyle: { color: '#4CAF50' } }, + { value: 7, name: '其他设备', itemStyle: { color: '#a0aec0' } } + ] + } + ] + }; + + this.pieChart.setOption(option); + }, + + initHistoryChart() { + if (!this.$refs.historyChart) return; + + this.historyChart = echarts.init(this.$refs.historyChart); + + const option = { + backgroundColor: 'transparent', + tooltip: { + trigger: 'axis' + }, + legend: { + data: ['CPU使用率', '内存使用率', '网络流量'], + textStyle: { + color: '#a0aec0' + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['10-18', '10-19', '10-20', '10-21', '10-22', '10-23', '10-24'], + axisLine: { + lineStyle: { + color: '#4dabff' + } + }, + axisLabel: { + color: '#a0aec0' + } + }, + yAxis: { + type: 'value', + axisLine: { + lineStyle: { + color: '#4dabff' + } + }, + axisLabel: { + color: '#a0aec0', + formatter: '{value}%' + }, + splitLine: { + lineStyle: { + color: 'rgba(77, 171, 255, 0.2)' + } + } + }, + series: [ + { + name: 'CPU使用率', + type: 'line', + smooth: true, + data: [45, 52, 48, 60, 55, 58, 62], + itemStyle: { + color: '#4dabff' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(77, 171, 255, 0.3)' + }, { + offset: 1, color: 'rgba(77, 171, 255, 0.1)' + }] + } + } + }, + { + name: '内存使用率', + type: 'line', + smooth: true, + data: [62, 58, 65, 70, 68, 72, 75], + itemStyle: { + color: '#62f7ff' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(98, 247, 255, 0.3)' + }, { + offset: 1, color: 'rgba(98, 247, 255, 0.1)' + }] + } + } + }, + { + name: '网络流量', + type: 'line', + smooth: true, + data: [78, 82, 75, 90, 85, 88, 95], + itemStyle: { + color: '#ffa726' + }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(255, 167, 38, 0.3)' + }, { + offset: 1, color: 'rgba(255, 167, 38, 0.1)' + }] + } + } + } + ] + }; + + this.historyChart.setOption(option); + }, + + generateDataFlows() { + // 生成数据流动画元素 + const flows = []; + const width = window.innerWidth; + const height = window.innerHeight; + + for (let i = 0; i < 20; i++) { + const startX = Math.random() * width; + const startY = Math.random() * height; + const targetX = Math.random() * width; + const targetY = Math.random() * height; + + flows.push({ + x: startX, + y: startY, + tx: targetX - startX, + ty: targetY - startY, + delay: Math.random() * 5 + }); + } + + this.dataFlows = flows; + }, + + handleResize() { + // 重新生成数据流 + this.generateDataFlows(); + + // 重新调整图表大小 + if (this.barChart) { + this.barChart.resize(); + } + if (this.pieChart) { + this.pieChart.resize(); + } + if (this.historyChart) { + this.historyChart.resize(); + } + }, + + updateData() { + // 模拟数据更新 + this.warningStats.total = Math.floor(15 + Math.random() * 10); + this.warningStats.highLevel = Math.floor(3 + Math.random() * 5); + this.warningStats.mediumLevel = Math.floor(5 + Math.random() * 8); + this.warningStats.lowLevel = this.warningStats.total - this.warningStats.highLevel - this.warningStats.mediumLevel; + + this.onlineDevices = Math.floor(90 + Math.random() * 15); + + // 更新设备状态 + this.deviceStatus.forEach(device => { + if (device.status === 'normal' && Math.random() > 0.7) { + device.status = Math.random() > 0.5 ? 'warning' : 'error'; + } else if (device.status !== 'normal' && Math.random() > 0.8) { + device.status = 'normal'; + } + + // 更新设备数值 + if (device.status === 'normal') { + device.value = Math.floor(85 + Math.random() * 15) + '%'; + } else if (device.status === 'warning') { + device.value = Math.floor(60 + Math.random() * 20) + '%'; + } else { + device.value = Math.floor(30 + Math.random() * 30) + '%'; + } + }); + + // 更新楼宇设备状态 + this.floors.forEach(floor => { + floor.devices.forEach(device => { + if (device.status === 'normal' && Math.random() > 0.8) { + device.status = Math.random() > 0.5 ? 'warning' : 'error'; + } else if (device.status !== 'normal' && Math.random() > 0.9) { + device.status = 'normal'; + } + }); + + // 更新楼层统计 + floor.onlineDevices = floor.devices.filter(d => d.status === 'normal').length; + floor.warningDevices = floor.devices.filter(d => d.status !== 'normal').length; + }); + + // 更新图表数据 + if (this.barChart) { + const option = this.barChart.getOption(); + option.series[0].data = option.series[0].data.map(() => Math.floor(20 + Math.random() * 20)); + option.series[1].data = option.series[1].data.map(() => Math.floor(1 + Math.random() * 8)); + option.series[2].data = option.series[2].data.map(() => Math.floor(0 + Math.random() * 3)); + this.barChart.setOption(option); + } + + this.updateTime = this.currentTime; + }, - + \ No newline at end of file