【web】 首页UI调整

dev
Wangxin 9 months ago
parent 0cf75ce555
commit a548944f67
  1. 2
      ALOps_sys_fe/alops-ui/src/api/inMonitoring/devicesState.js
  2. 92
      ALOps_sys_fe/alops-ui/src/api/index/index.js
  3. 2
      ALOps_sys_fe/alops-ui/src/router/index.js
  4. 10
      ALOps_sys_fe/alops-ui/src/views/device/files/index.vue
  5. 514
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/cardItem.vue
  6. 839
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/detail.vue
  7. 69
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/history.vue
  8. 30
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/index.vue
  9. 3
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/inMonitor/message/index.vue
  10. 4
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/inMonitor/rules/index.vue
  11. 91
      ALOps_sys_fe/alops-ui/src/views/index.vue

@ -5,7 +5,7 @@ const api = '/device/files/'
// 查询多台设备列表
export function list(query) {
return request({
url: api + 'listMonitor',
url: api + 'list',
method: 'get',
params: query
})

@ -0,0 +1,92 @@
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi";
const api = '/device/files/'
// 查询详细
export function getDict() {
return request({
url: '/sys_dict',
method: 'get'
})
}
// 预警信息统
export function statistic(query) {
return request({
url: 'inMonitoring/statistic',
method: 'get',
params: query
})
}
// 统计预警信息次数
export function alertMessageTimes(query) {
return request({
url: 'inMonitoring/alertMessage/times',
method: 'get',
params: query
})
}
// 按设备类型分类统计设备信息
export function byEquType() {
return request({
url: 'device/files/byEquType',
method: 'get'
})
}
// 设备运行状态
export function listMonitor(query) {
return request({
url: 'device/files/monitorById',
method: 'get',
params: query
})
}
// 查询详细
export function getInfo(id) {
return request({
url: api + '/queryById/' + parseStrEmpty(id),
method: 'get'
})
}
// 新增
export function add(data) {
return request({
url: api + 'add',
method: 'post',
data: data
})
}
// 修改
export function update(data) {
return request({
url: api + 'modify',
method: 'put',
data: data
})
}
// 删除
export function del(id) {
return request({
url: api + id,
method: 'delete'
})
}

@ -99,7 +99,7 @@ export const dynamicRoutes = [
permissions: ['inMonitoring:devicesState:edit'],
children: [
{
path: 'detail/:userId(\\d+)',
path: 'detail/:userId',
component: () => import('@/views/inMonitoring/devicesState/detail'),
name: 'DevicesStateDetail',
meta: { title: '设备详情', activeMenu: '/inMonitoring/devicesState-detail' }

@ -33,9 +33,9 @@
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['device:files:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['device:files:import']">导入</el-button>
</el-col>
</el-col> -->
</el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
@ -119,7 +119,9 @@
</el-col>
<el-col :span="12">
<el-form-item label="设备级别" prop="deviceLevel">
<el-input v-model="form.deviceLevel" placeholder="请输入设备级别" maxlength="30" />
<el-select v-model="form.deviceLevel" placeholder="设备级别" clearable style="width: 240px">
<el-option v-for="dict in dict.type.warning_level" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@ -205,7 +207,7 @@ import "splitpanes/dist/splitpanes.css"
export default {
name: "User",
dicts: ['device_disable', 'sys_user_sex'],
dicts: ['device_disable', 'sys_user_sex', 'warning_level'],
components: { Treeselect, Splitpanes, Pane },
data() {
return {

@ -1,75 +1,485 @@
<template>
<div class="">
<h3 class="h3" @click="handleDetail">交换机</h3>
<el-row>
<el-col :span="14">
<img src="../../../assets/images/profile.jpg" width="100%" alt="" srcset="">
</el-col>
<el-col :span="9" offset="1">
<p>
<span>在线状态:</span><br/>
<span>在线</span>
</p>
<p>
<span>设备级别:</span><br/>
<span>A</span>
</p>
<p>
<span>安装位置:</span><br/>
<span>在线</span>
</p>
<p>
<span>品牌型号:</span><br/>
<span>在线</span>
</p>
</el-col>
</el-row>
<el-divider></el-divider>
<el-row>
<el-col :span="7">
<BarChart2 height="100px"></BarChart2>
</el-col>
<el-col :span="7">
<BarChart height="100px"></BarChart>
</el-col>
<el-col :span="10">
<el-button round type="danger" size="mini">危险</el-button>
<p>
<span>待处理预警数:</span>
<span>待开发</span>
</p>
<p>
<span>预警总数:</span>
<span>待开发</span>
</p>
</el-col>
</el-row>
<div class="body" @click="handleDetail(cardData)">
<div class="dashboard">
<!-- 上层左侧图片右侧参数 -->
<div class="top-section">
<!-- 左侧图片 -->
<div class="card">
<div class="card-header">
<h2 class="card-title">
<i class="fas fa-network-wired"></i>
{{cardData.name}}
</h2>
<span class="status-badge status-online">
<i class="fas fa-circle"></i> 在线
</span>
</div>
<div class="device-box">
<div class="device-image">
<i class="fas fa-server"></i>
</div>
<div class="device-info">
<div class="info-item">
<span class="info-label">
<i class="fas fa-layer-group"></i> 设备级别
</span>
<span class="info-value">A级</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-map-marker-alt"></i> 安装位置
</span>
<span class="info-value">一层</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-tag"></i> 品牌型号
</span>
<span class="info-value">Cisco</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 运行状态
</span>
<span class="info-value">运行正常</span>
</div>
</div>
</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-value cpu-usage">66%</div>
<div class="metric-label">CPU占用</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 66%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-value cpu-usage">66%</div>
<div class="metric-label">内存占用</div>
<div class="progress-bar">
<div class="progress-fill" style="width: 66%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-value alert-pending">待开发</div>
<div class="metric-label">待处理预警数</div>
</div>
<div class="metric-card">
<div class="metric-value alert-total">待开发</div>
<div class="metric-label">预警总数</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import BarChart from './BarChart1.vue'
import BarChart2 from './BarChart2.vue'
export default {
name: "cardItem",
components: { BarChart, BarChart2 },
props: {
cardData: {
type: Object,
default: () => ({})
}
},
data() {
return {
}
},
created() {
mounted() {
// this.initCharts();
},
methods: {
initCharts() {
//
const performanceChart = echarts.init(document.getElementById('performanceChart'));
performanceChart.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['CPU使用率', '内存使用率'],
textStyle: {
color: '#718096'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096',
formatter: '{value}%'
},
splitLine: {
lineStyle: {
color: 'rgba(203, 213, 224, 0.6)'
}
}
},
series: [
{
name: 'CPU使用率',
type: 'line',
smooth: true,
data: [45, 52, 38, 66, 58, 62, 48],
lineStyle: {
color: '#ed8936'
},
itemStyle: {
color: '#ed8936'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(237, 137, 54, 0.3)'
}, {
offset: 1, color: 'rgba(237, 137, 54, 0.1)'
}]
}
}
},
{
name: '内存使用率',
type: 'line',
smooth: true,
data: [30, 45, 35, 50, 42, 38, 32],
lineStyle: {
color: '#4299e1'
},
itemStyle: {
color: '#4299e1'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(66, 153, 225, 0.3)'
}, {
offset: 1, color: 'rgba(66, 153, 225, 0.1)'
}]
}
}
}
]
});
//
window.addEventListener('resize', function() {
performanceChart.resize();
trafficChart.resize();
});
},
/** 查看详情 */
handleDetail: function(row) {
console.log("%c 🖍: row ", "font-size:16px;background-color:#3c235b;color:white;", row)
const userId = row.pointerId
console.log("%c 🐋: row ", "font-size:16px;background-color:#46dc4d;color:black;", row)
const userId = row.id
this.$router.push("/inMonitoring/devicesState-detail/detail/" + userId)
},
}
}
</script>
</script>
<style lang="scss" scoped>
.body {
color: #2d3748;
line-height: 1.6;
min-height: 100vh;
}
.dashboard {
max-width: 1400px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 40px;
padding: 25px;
border-radius: 20px;
}
.header h1 {
color: #2d3748;
margin-bottom: 10px;
font-size: 36px;
font-weight: 700;
background: linear-gradient(90deg, #4299e1, #38b2ac);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header p {
color: #718096;
font-size: 18px;
}
.top-section {
display: grid;
// grid-template-columns: 1fr 2fr;
gap: 30px;
}
.bottom-section {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 30px;
}
.card {
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
padding: 10px 30px 30px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.9);
transition: all 0.4s ease;
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #4299e1, #38b2ac);
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.12);
border-color: rgba(66, 153, 225, 0.3);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
// padding-bottom: 15px;
border-bottom: 1px solid rgba(226, 232, 240, 0.8);
}
.card-title {
font-size: 22px;
font-weight: 700;
color: #2d3748;
display: flex;
align-items: center;
gap: 12px;
}
.card-title i {
color: #4299e1;
font-size: 24px;
}
.status-badge {
padding: 6px 15px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
}
.status-online {
background: rgba(72, 187, 120, 0.15);
color: #38a169;
border: 1px solid rgba(72, 187, 120, 0.3);
}
.status-danger {
background: rgba(245, 101, 101, 0.15);
color: #e53e3e;
border: 1px solid rgba(245, 101, 101, 0.3);
}
.device-image {
width: 100%;
height: 280px;
background: linear-gradient(135deg, #edf2f7, #e2e8f0);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border: 1px solid rgba(226, 232, 240, 0.8);
}
.device-image i {
font-size: 80px;
color: #4299e1;
opacity: 0.8;
}
.device-box {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 15px;
}
.device-info {
display: grid;
grid-template-columns: 1fr;
gap: 15px;
}
.info-item {
display: flex;
flex-direction: column;
padding: 4px 12px;
background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
transition: all 0.3s ease;
}
.info-item:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.info-label {
font-size: 13px;
color: #718096;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.info-label i {
font-size: 12px;
color: #4299e1;
}
.info-value {
font-size: 14px;
font-weight: 600;
color: #2d3748;
}
.chart-container {
width: 100%;
height: 300px;
margin-top: 10px;
}
.metrics-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 20px;
}
.metric-card {
padding: 10px;
background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
text-align: center;
transition: all 0.3s ease;
}
.metric-card:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.metric-value {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
}
.metric-label {
font-size: 14px;
color: #718096;
}
.cpu-usage {
color: #ed8936;
}
.alert-pending {
color: #e53e3e;
}
.alert-total {
color: #4299e1;
}
.progress-bar {
height: 8px;
background: rgba(226, 232, 240, 0.8);
border-radius: 4px;
overflow: hidden;
margin-top: 10px;
}
.progress-fill {
height: 100%;
border-radius: 4px;
transition: width 0.8s ease;
background: linear-gradient(90deg, #ed8936, #dd6b20);
box-shadow: 0 0 10px rgba(237, 137, 54, 0.3);
}
@media (max-width: 1024px) {
.top-section, .bottom-section {
grid-template-columns: 1fr;
}
}
</style>

@ -1,198 +1,679 @@
<template>
<div class="app-container">
<el-row :gutter="5">
<el-col :span="24">
<el-card>
<el-row>
<el-col :span="4">
<h3>交换机</h3>
</el-col>
<el-col :span="4">
<h3>持续在线XXXXX小时</h3>
</el-col>
</el-row>
<el-divider></el-divider>
<div class="body">
<div class="dashboard">
<!-- 上层左侧图片右侧参数 -->
<div class="top-section0">
<div class="card">
<div class="card-header">
<h2 class="card-title">
<i class="fas fa-network-wired"></i>
设备概览
</h2>
<span class="status-badge status-online">
<i class="fas fa-circle"></i> 在线
</span>
</div>
<div class="top-section-con">
<div class="device-image">
<i class="fas fa-server"></i>
</div>
<!-- 设备基本信息 -->
<div class="device-info">
<div class="info-title">设备基本信息</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-layer-group"></i> 设备级别
</span>
<span class="info-value">A级</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-map-marker-alt"></i> 安装位置
</span>
<span class="info-value">数据中心-主柜</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-tag"></i> 品牌型号
</span>
<span class="info-value">Cisco</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 运行状态
</span>
<span class="info-value">运行正常</span>
</div>
</div>
<el-row>
<el-col :span="8">
<h3>交换机</h3>
</el-col>
<el-col :span="4">
<h3>设备基本信息</h3>
<p>
<span>设备型号:</span>
<span>待开发</span>
</p>
<p>
<span>设备级别:</span>
<span>待开发</span>
</p>
<p>
<span>设备版本:</span>
<span>待开发</span>
</p>
<p>
<span>设备类型:</span>
<span>待开发</span>
</p>
</el-col>
<el-col :span="4">
<h3>设备出厂信息</h3>
<p>
<span>生产商名称:</span>
<span>待开发</span>
</p>
<p>
<span>供货商名称:</span>
<span>待开发</span>
</p>
<p>
<span>出厂日期:</span>
<span>待开发</span>
</p>
<p>
<span>质保时间:</span>
<span>待开发</span>
</p>
<p>
<span>联系人:</span>
<span>待开发</span>
</p>
<p>
<span>联系电话:</span>
<span>待开发</span>
</p>
</el-col>
<el-col :span="4">
<h3>设备管理信息</h3>
<p>
<span>带外IP管理:</span>
<span>待开发</span>
</p>
<p>
<span>安装位置:</span>
<span>待开发</span>
</p>
<p>
<span>安装日期:</span>
<span>待开发</span>
</p>
<p>
<span>服役年限:</span>
<span>待开发</span>
</p>
<p>
<span>管理员:</span>
<span>待开发</span>
</p>
</el-col>
<el-col :span="4">
<h3>设备状态信息</h3>
<p>
<span>累计预警次数:</span>
<span>待开发</span>
</p>
<p>
<span>累计维修次数:</span>
<span>待开发</span>
</p>
</el-col>
</el-row>
</el-card>
</el-col>
</el-row>
<el-row class="mt10" :gutter="10">
<el-col :span="12">
<el-card :style="{height: '500px'}">
<el-row>
<el-col :span="24" class="flex alignItems gap10">
<h3>设备运行数据</h3>
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</el-col>
<el-col :span="14">
<el-row>
<el-col :span="12">
<LineChart></LineChart>
</el-col>
<el-col :span="12">
<LineChart></LineChart>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<LineChart></LineChart>
</el-col>
<el-col :span="12">
<LineChart></LineChart>
</el-col>
</el-row>
</el-col>
<el-col :span="10">
<el-row>
<el-col :span="12">
<BarChart height="200px" :dateRange="dateRange"></BarChart>
</el-col>
<el-col :span="12">
<BarChart height="200px" :dateRange="dateRange"></BarChart>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<BarChart2 height="200px" :dateRange="dateRange"></BarChart2>
</el-col>
<el-col :span="8">
<BarChart2 height="200px" :dateRange="dateRange"></BarChart2>
</el-col>
<el-col :span="8">
<BarChart2 height="200px" :dateRange="dateRange"></BarChart2>
</el-col>
</el-row>
</el-col>
<!-- 设备基本信息 -->
<div class="device-info">
<div class="info-title">设备基本信息</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-layer-group"></i> 设备级别
</span>
<span class="info-value">A级</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-map-marker-alt"></i> 安装位置
</span>
<span class="info-value">数据中心-主柜</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-tag"></i> 品牌型号
</span>
<span class="info-value">Cisco</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 运行状态
</span>
<span class="info-value">运行正常</span>
</div>
</div>
</el-row>
</el-card>
</el-col>
<el-col :span="12">
<el-card :style="{height: '500px'}">
<el-tabs v-model="selectedTab">
<el-tab-pane label="历史预警" :name="1">
历史预警
</el-tab-pane>
<el-tab-pane label="接口信息" :name="2">
接口信息
</el-tab-pane>
<el-tab-pane label="其他指标" :name="3">
其他指标
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</div>
<!-- 设备基本信息 -->
<div class="device-info">
<div class="info-title">设备基本信息</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-layer-group"></i> 设备级别
</span>
<span class="info-value">A级</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-map-marker-alt"></i> 安装位置
</span>
<span class="info-value">数据中心-主柜</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-tag"></i> 品牌型号
</span>
<span class="info-value">Cisco</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 运行状态
</span>
<span class="info-value">运行正常</span>
</div>
</div>
<!-- 设备基本信息 -->
<div class="device-info">
<div class="info-title">设备基本信息</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-layer-group"></i> 设备级别
</span>
<span class="info-value">A级</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-map-marker-alt"></i> 安装位置
</span>
<span class="info-value">数据中心-主柜</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-tag"></i> 品牌型号
</span>
<span class="info-value">Cisco</span>
</div>
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 运行状态
</span>
<span class="info-value">运行正常</span>
</div>
</div>
</div>
</div>
</div>
<!-- 下层图表加参数 -->
<div class="bottom-section">
<!-- 左侧图表 -->
<div class="card">
<div class="card-header">
<h2 class="card-title">
<i class="fas fa-chart-bar"></i>
设备运行数据
</h2>
<el-date-picker
v-model="daterange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
<div class="chart-container" id="performanceChart"></div>
<div class="chart-container" id="trafficChart"></div>
</div>
<!-- 右侧参数 -->
<div class="card">
<div class="card-header">
<div class="tab-top">
<div class="top-item" v-for="(i,k) in tabs" :key="k" :class="k == tabIndex ?'ac':''" @click="tabIndex = k">
<span>{{ i.name }}</span>
</div>
</div>
</div>
<div class="metrics-grid">
<div class="bottom-item" v-if="tabIndex == 0">
<History/>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import BarChart from './BarChart1.vue'
import LineChart from './LineChart.vue'
import BarChart2 from './BarChart2.vue'
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import History from './history.vue'
export default {
name: "cardItem",
components: { BarChart, BarChart2, LineChart },
components: { History },
data() {
return {
dateRange: [],
selectedTab: 1
selectedTab: 1,
tabs: [
{ name: '历史预警' },
{ name: '接口信息' },
{ name: 'VLAN信息' },
{ name: '路由表信息' },
],
tabIndex: 0,
}
},
created() {
},
mounted() {
this.initCharts();
},
methods: {
initCharts() {
//
const performanceChart = echarts.init(document.getElementById('performanceChart'));
performanceChart.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['CPU使用率', '内存使用率'],
textStyle: {
color: '#718096'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096',
formatter: '{value}%'
},
splitLine: {
lineStyle: {
color: 'rgba(203, 213, 224, 0.6)'
}
}
},
series: [
{
name: 'CPU使用率',
type: 'line',
smooth: true,
data: [45, 52, 38, 66, 58, 62, 48],
lineStyle: {
color: '#ed8936'
},
itemStyle: {
color: '#ed8936'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(237, 137, 54, 0.3)'
}, {
offset: 1, color: 'rgba(237, 137, 54, 0.1)'
}]
}
}
},
{
name: '内存使用率',
type: 'line',
smooth: true,
data: [30, 45, 35, 50, 42, 38, 32],
lineStyle: {
color: '#4299e1'
},
itemStyle: {
color: '#4299e1'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(66, 153, 225, 0.3)'
}, {
offset: 1, color: 'rgba(66, 153, 225, 0.1)'
}]
}
}
}
]
});
//
const trafficChart = echarts.init(document.getElementById('trafficChart'));
trafficChart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['入站流量', '出站流量'],
textStyle: {
color: '#718096'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
}
},
yAxis: {
type: 'value',
name: 'MB/s',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
},
splitLine: {
lineStyle: {
color: 'rgba(203, 213, 224, 0.6)'
}
}
},
series: [
{
name: '入站流量',
type: 'bar',
data: [320, 332, 301, 334, 390, 330, 320],
itemStyle: {
color: '#4299e1'
}
},
{
name: '出站流量',
type: 'bar',
data: [220, 182, 191, 234, 290, 330, 310],
itemStyle: {
color: '#ed8936'
}
}
]
});
//
window.addEventListener('resize', function() {
performanceChart.resize();
trafficChart.resize();
});
}
}
}
</script>
<style lang="less" scoped>
<style scoped>
.body {
background: linear-gradient(135deg, #f8fafc, #e2e8f0);
color: #2d3748;
line-height: 1.6;
padding: 20px;
min-height: 100vh;
}
.dashboard {
max-width: 1400px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 40px;
padding: 25px;
background: rgba(255, 255, 255, 0.8);
border-radius: 20px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.9);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
}
.header h1 {
color: #2d3748;
margin-bottom: 10px;
font-size: 36px;
font-weight: 700;
background: linear-gradient(90deg, #4299e1, #38b2ac);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header p {
color: #718096;
font-size: 18px;
}
.top-section0 {
margin-bottom: 20px;
}
.top-section-con {
display: grid;
grid-template-columns: 3fr 1fr 1fr 1fr 1fr;
gap: 30px;
}
.top-section {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 30px;
margin-bottom: 30px;
}
.bottom-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.card {
background: rgba(255, 255, 255, 0.9);
border-radius: 20px;
padding: 30px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.9);
transition: all 0.4s ease;
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #4299e1, #38b2ac);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 25px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(226, 232, 240, 0.8);
}
.card-title {
font-size: 18px;
font-weight: 700;
color: #2d3748;
display: flex;
align-items: center;
gap: 12px;
}
.card-title i {
color: #4299e1;
font-size: 24px;
}
.status-badge {
padding: 6px 15px;
border-radius: 20px;
font-size: 13px;
font-weight: 600;
}
.status-online {
background: rgba(72, 187, 120, 0.15);
color: #38a169;
border: 1px solid rgba(72, 187, 120, 0.3);
}
.status-danger {
background: rgba(245, 101, 101, 0.15);
color: #e53e3e;
border: 1px solid rgba(245, 101, 101, 0.3);
}
.device-image {
width: 100%;
height: 400px;
background: linear-gradient(135deg, #edf2f7, #e2e8f0);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
/* margin-bottom: 20px; */
overflow: hidden;
border: 1px solid rgba(226, 232, 240, 0.8);
}
.device-image i {
font-size: 80px;
color: #4299e1;
opacity: 0.8;
}
.device-info {
display: grid;
grid-template-columns: 1fr;
gap: 15px;
}
.info-title {
color: #2d3748;
font-size: 16px;
font-weight: 600;
text-align: center;
}
.info-item {
display: flex;
flex-direction: column;
padding: 12px;
background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
transition: all 0.3s ease;
}
.info-item:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.info-label {
font-size: 13px;
color: #718096;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.info-label i {
font-size: 12px;
color: #4299e1;
}
.info-value {
font-size: 14px;
font-weight: 600;
color: #2d3748;
}
.chart-container {
width: 100%;
height: 300px;
margin-top: 10px;
}
.metrics-grid {
margin-top: 20px;
}
.metric-card {
padding: 20px;
background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
text-align: center;
transition: all 0.3s ease;
}
.metric-card:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.metric-value {
font-size: 32px;
font-weight: 700;
margin-bottom: 8px;
}
.metric-label {
font-size: 14px;
color: #718096;
}
.cpu-usage {
color: #ed8936;
}
.alert-pending {
color: #e53e3e;
}
.alert-total {
color: #4299e1;
}
.progress-bar {
height: 8px;
background: rgba(226, 232, 240, 0.8);
border-radius: 4px;
overflow: hidden;
margin-top: 10px;
}
.progress-fill {
height: 100%;
border-radius: 4px;
transition: width 0.8s ease;
background: linear-gradient(90deg, #ed8936, #dd6b20);
box-shadow: 0 0 10px rgba(237, 137, 54, 0.3);
}
@media (max-width: 1024px) {
.top-section, .bottom-section {
grid-template-columns: 1fr;
}
}
</style>
.tab-top{
display: flex;
gap: 20px;
}
.top-item{
color: #2d3748;
font-weight: 400;
font-size:18px ;
cursor: pointer;
}
.top-item.ac{
font-weight: 600;
border-bottom: 2px solid #2d3748;
}
</style>

@ -0,0 +1,69 @@
<template>
<div class="">
<el-row :gutter="20">
<el-col>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="预警时间" align="center" key="id" prop="id"/>
<el-table-column label="预警等级" align="center" key="name" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="预警信息" align="center" key="description" prop="description" :show-overflow-tooltip="true" />
<el-table-column label="预警状态" align="center" key="createBy" prop="createBy" :show-overflow-tooltip="true" />
<el-table-column label="处理人" align="center" key="createBy" prop="createBy" :show-overflow-tooltip="true" />
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</el-col>
</el-row>
</div>
</template>
<script>
import { list, del, add, update } from "@/api/device/deviceType"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
export default {
name: "User",
dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect, Splitpanes, Pane },
data() {
return {
//
loading: true,
//
total: 0,
//
userList: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined
},
}
},
created() {
this.getList()
},
methods: {
/** 查询类型列表 */
getList() {
this.loading = true
list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.rows
this.total = response.total
this.loading = false
}
)
}
}
}
</script>

@ -36,12 +36,10 @@
</el-form-item>
</el-form>
<div class="app-container" v-loading="loading">
<div class="bodyBox" v-loading="loading">
<el-row :gutter="10">
<el-col :span="8" class="card-box" v-for="(i,k) in userList" :key="k" @click="handleDetail(i)">
<el-card>
<cardItem/>
</el-card>
<el-col :span="8" class="card-box" v-for="(i,k) in userList" :key="k" >
<cardItem class="cursor" :cardData="i"/>
</el-col>
</el-row>
</div>
@ -148,7 +146,7 @@
</template>
<script>
import { list, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/inMonitoring/devicesState"
import { list, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/inMonitoring/devicesState"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import cardItem from "./cardItem.vue"
@ -379,11 +377,6 @@ export default {
this.form.password = this.initPassword
})
},
/** 查看详情 */
handleDetail: function(row) {
const userId = row.userId
this.$router.push("/inMonitoring/devicesState-detail/detail/" + userId)
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
@ -482,4 +475,17 @@ export default {
}
}
}
</script>
</script>
<style scoped>
.bodyBox{
background: linear-gradient(135deg, #f8fafc, #e2e8f0);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.9);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
padding: 10px;
}
.cursor{
cursor: pointer;
}
</style>

@ -19,9 +19,6 @@
<el-option v-for="dict in dict.type.alert_message_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="位置" prop="location">
<el-input v-model="queryParams.phonenumber" placeholder="请输入位置" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>

@ -7,7 +7,7 @@
<el-col>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="预警级别">
<el-select v-model="form.sex" placeholder="请选择级别" style="width: 100%">
<el-select v-model="queryParams.severity" placeholder="请选择级别" style="width: 100%">
<el-option v-for="dict in dict.type.warning_level" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
@ -112,7 +112,7 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="24" v-show="form.alertWay == 'email'">
<el-col :span="24" v-if="form.alertWay == 'email'">
<el-form-item label="邮箱" prop="alertStation">
<el-input v-model="form.alertStation" placeholder="请输入邮箱" />
</el-form-item>

@ -7,7 +7,7 @@
<div class="panel">
<div class="card">
<div class="card-header">
<h2 class="card-title"><i class="fas fa-exclamation-triangle"></i> 预警信息统计1</h2>
<h2 class="card-title"><i class="fas fa-exclamation-triangle"></i> 预警信息统计</h2>
</div>
<div class="stats-container">
<div class="stat-card">
@ -132,6 +132,12 @@ import RaddarChart from './dashboard/RaddarChart'
import PieChart from './dashboard/PieChart'
import BarChart from './dashboard/BarChart'
import digital from './dashboard/digital'
import { statistic, byEquType, listMonitor, alertMessageTimes } from "@/api/index/index"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import { Splitpanes, Pane } from "splitpanes"
import "splitpanes/dist/splitpanes.css"
export default {
name: 'Index',
@ -174,7 +180,47 @@ export default {
level: 0,
status: 'normal',
icon: 'fas fa-check-circle'
}
},
{
id: 1,
deviceName: 'PLC远程监控系统',
time: '2021-10-16 14:54:11',
location: '污水处理监控系统',
message: '2#电机运行状态等于1',
level: 1,
status: 'warning',
icon: 'fas fa-exclamation-circle'
},
{
id: 2,
deviceName: 'PLC远程监控系统',
time: '2021-10-16 14:54:04',
location: '污水处理监控系统',
message: '2#电机运行状态报警恢复',
level: 0,
status: 'normal',
icon: 'fas fa-check-circle'
},
{
id: 1,
deviceName: 'PLC远程监控系统',
time: '2021-10-16 14:54:11',
location: '污水处理监控系统',
message: '2#电机运行状态等于1',
level: 1,
status: 'warning',
icon: 'fas fa-exclamation-circle'
},
{
id: 2,
deviceName: 'PLC远程监控系统',
time: '2021-10-16 14:54:04',
location: '污水处理监控系统',
message: '2#电机运行状态报警恢复',
level: 0,
status: 'normal',
icon: 'fas fa-check-circle'
},
],
tableHeaders: ['设备名称', '设备位置', 'CPU使用率', '内存使用率', '温度', '健康度', '设备运行时长', '采集时间'],
deviceStatus: [
@ -240,8 +286,45 @@ export default {
if (health >= 80) return 'health-good';
if (health >= 60) return 'health-warning';
return 'health-critical';
}
}
},
getstatistic() {
this.loading = true
statistic().then(response => {
console.log("%c 🎹: getList -> response ", "font-size:16px;background-color:#624a64;color:white;", response)
this.loading = false
}
)
},
getbyEquType() {
this.loading = true
byEquType().then(response => {
this.loading = false
}
)
},
getlistMonitor() {
this.loading = true
listMonitor({id:11}).then(response => {
this.loading = false
}
)
},
getalertMessageTimes() {
this.loading = true
alertMessageTimes().then(response => {
this.loading = false
}
)
},
},
created() {
this.getstatistic()
this.getbyEquType()
this.getlistMonitor()
this.getalertMessageTimes()
},
}
</script>

Loading…
Cancel
Save