<template>
|
<div class="dashboard-container">
|
<!-- 统计卡片 -->
|
<el-row :gutter="20">
|
<el-col :span="6">
|
<el-card class="statistics-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-title">设备在线率</div>
|
<div class="card-value">{{ onlineRate }}%</div>
|
<div class="card-desc">当前在线设备数:{{ onlineCount }} / {{ totalDevices }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="statistics-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-title">故障预警数</div>
|
<div class="card-value">{{ warningCount }}</div>
|
<div class="card-desc">高风险:{{ highRiskCount }} | 中风险:{{ mediumRiskCount }} | 低风险:{{ lowRiskCount }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="statistics-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-title">待处理维修单</div>
|
<div class="card-value">{{ pendingOrders }}</div>
|
<div class="card-desc">处理中:{{ processingOrders }} | 已完成:{{ completedOrders }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="statistics-card" shadow="hover">
|
<div class="card-content">
|
<div class="card-title">重点设备运行状态</div>
|
<div class="card-value">{{ normalDevices }} 正常</div>
|
<div class="card-desc">异常:{{ abnormalDevices }} | 故障:{{ faultDevices }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 图表区域 -->
|
<el-row :gutter="20" style="margin-top: 20px;">
|
<!-- 设备健康度趋势图 -->
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>设备健康度趋势图</span>
|
</div>
|
</template>
|
<div ref="healthChartRef" class="chart-container"></div>
|
</el-card>
|
</el-col>
|
<!-- 近7日故障类型统计 -->
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<template #header>
|
<div class="card-header">
|
<span>近7日故障类型统计</span>
|
</div>
|
</template>
|
<div ref="faultChartRef" class="chart-container"></div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 重点设备运行状态卡片 -->
|
<el-card shadow="hover" style="margin-top: 20px;">
|
<template #header>
|
<div class="card-header">
|
<span>重点设备运行状态</span>
|
</div>
|
</template>
|
<el-table :data="keyDevices" stripe style="width: 100%">
|
<el-table-column prop="name" label="设备名称" width="180"></el-table-column>
|
<el-table-column prop="model" label="型号" width="120"></el-table-column>
|
<el-table-column prop="ip" label="IP地址" width="150"></el-table-column>
|
<el-table-column prop="status" label="状态" width="100">
|
<template #default="scope">
|
<el-tag :type="scope.row.status === 'online' ? 'success' : scope.row.status === 'warning' ? 'warning' : 'danger'">
|
{{ scope.row.status === 'online' ? '在线' : scope.row.status === 'warning' ? '预警' : '故障' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="temperature" label="温度(℃)" width="100"></el-table-column>
|
<el-table-column prop="pressure" label="压力(MPa)" width="100"></el-table-column>
|
<el-table-column prop="speed" label="转速(rpm)" width="100"></el-table-column>
|
<el-table-column prop="health" label="健康度" width="120">
|
<template #default="scope">
|
<el-progress :percentage="scope.row.health" :stroke-width="10"></el-progress>
|
</template>
|
</el-table-column>
|
</el-table>
|
</el-card>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, onMounted, onUnmounted } from 'vue'
|
import * as echarts from 'echarts'
|
|
// 统计数据
|
const onlineRate = ref(85)
|
const onlineCount = ref(170)
|
const totalDevices = ref(200)
|
const warningCount = ref(23)
|
const highRiskCount = ref(5)
|
const mediumRiskCount = ref(12)
|
const lowRiskCount = ref(6)
|
const pendingOrders = ref(15)
|
const processingOrders = ref(8)
|
const completedOrders = ref(45)
|
const normalDevices = ref(162)
|
const abnormalDevices = ref(18)
|
const faultDevices = ref(10)
|
|
// 重点设备列表
|
const keyDevices = ref([
|
{ name: '空压机A-001', model: 'KA-200', ip: '192.168.1.101', status: 'online', temperature: 42, pressure: 0.8, speed: 1450, health: 92 },
|
{ name: '冷却塔B-002', model: 'CT-300', ip: '192.168.1.102', status: 'warning', temperature: 58, pressure: 0.6, speed: 980, health: 75 },
|
{ name: '水泵C-003', model: 'WP-150', ip: '192.168.1.103', status: 'online', temperature: 38, pressure: 1.2, speed: 1200, health: 88 },
|
{ name: '发电机D-004', model: 'GE-500', ip: '192.168.1.104', status: 'danger', temperature: 75, pressure: 0.5, speed: 1500, health: 60 },
|
{ name: '变压器E-005', model: 'TR-1000', ip: '192.168.1.105', status: 'online', temperature: 45, pressure: 0, speed: 0, health: 95 }
|
])
|
|
// 图表引用
|
const healthChartRef = ref(null)
|
const faultChartRef = ref(null)
|
let healthChart = null
|
let faultChart = null
|
|
// 健康度趋势数据
|
const healthTrendData = {
|
dates: ['12-10', '12-11', '12-12', '12-13', '12-14', '12-15', '12-16'],
|
values: [88, 90, 85, 87, 92, 91, 93]
|
}
|
|
// 故障类型统计数据
|
const faultTypeData = {
|
types: ['温度异常', '压力超标', '转速异常', '振动过大', '其他'],
|
values: [15, 8, 12, 6, 3]
|
}
|
|
// 初始化健康度趋势图
|
const initHealthChart = () => {
|
if (healthChartRef.value) {
|
healthChart = echarts.init(healthChartRef.value)
|
const option = {
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'cross',
|
label: {
|
backgroundColor: '#6a7985'
|
}
|
}
|
},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'category',
|
boundaryGap: false,
|
data: healthTrendData.dates
|
},
|
yAxis: {
|
type: 'value',
|
min: 70,
|
max: 100,
|
name: '健康度(%)'
|
},
|
series: [
|
{
|
name: '健康度',
|
type: 'line',
|
stack: '总量',
|
areaStyle: {},
|
emphasis: {
|
focus: 'series'
|
},
|
data: healthTrendData.values,
|
itemStyle: {
|
color: '#67c23a'
|
},
|
lineStyle: {
|
width: 3
|
}
|
}
|
]
|
}
|
healthChart.setOption(option)
|
}
|
}
|
|
// 初始化故障类型统计饼图
|
const initFaultChart = () => {
|
if (faultChartRef.value) {
|
faultChart = echarts.init(faultChartRef.value)
|
const option = {
|
tooltip: {
|
trigger: 'item'
|
},
|
legend: {
|
orient: 'vertical',
|
left: 'left'
|
},
|
series: [
|
{
|
name: '故障类型',
|
type: 'pie',
|
radius: '50%',
|
data: faultTypeData.types.map((type, index) => ({
|
name: type,
|
value: faultTypeData.values[index]
|
})),
|
emphasis: {
|
itemStyle: {
|
shadowBlur: 10,
|
shadowOffsetX: 0,
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
}
|
}
|
}
|
]
|
}
|
faultChart.setOption(option)
|
}
|
}
|
|
// 监听窗口大小变化,调整图表大小
|
const handleResize = () => {
|
healthChart?.resize()
|
faultChart?.resize()
|
}
|
|
onMounted(() => {
|
initHealthChart()
|
initFaultChart()
|
window.addEventListener('resize', handleResize)
|
})
|
|
onUnmounted(() => {
|
window.removeEventListener('resize', handleResize)
|
healthChart?.dispose()
|
faultChart?.dispose()
|
})
|
</script>
|
|
<style scoped>
|
.dashboard-container {
|
padding: 20px;
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
}
|
|
.statistics-card {
|
height: 180px;
|
}
|
|
.card-content {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
justify-content: center;
|
align-items: center;
|
}
|
|
.card-title {
|
font-size: 16px;
|
color: #606266;
|
margin-bottom: 10px;
|
}
|
|
.card-value {
|
font-size: 32px;
|
font-weight: bold;
|
color: #303133;
|
margin-bottom: 8px;
|
}
|
|
.card-desc {
|
font-size: 14px;
|
color: #909399;
|
}
|
|
.card-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.chart-container {
|
width: 100%;
|
height: 350px;
|
}
|
</style>
|