|
|
@@ -0,0 +1,298 @@
|
|
|
+<template>
|
|
|
+ <div class="hot-monitor-container">
|
|
|
+ <div class="header-section">
|
|
|
+ <h1 class="page-title">余热监测</h1>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="dashboard-container">
|
|
|
+ <!-- 热水系统监控 -->
|
|
|
+ <el-card class="system-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="system-header">
|
|
|
+ <i class="el-icon-monitor"></i>
|
|
|
+ <span>热水系统监控</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12" v-for="item in hotWaterSystem" :key="item.id">
|
|
|
+ <div class="data-item">
|
|
|
+ <div class="item-label">{{ item.name }}</div>
|
|
|
+ <div class="item-value" :class="getValueClass(item)">
|
|
|
+ {{ getRandomValue(item.range) }} {{ item.unit }}
|
|
|
+ </div>
|
|
|
+ <div class="item-range">正常范围: {{ item.range }} {{ item.unit }}</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 车间温度监控 -->
|
|
|
+ <el-row :gutter="20" class="temperature-section">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card class="system-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="system-header">
|
|
|
+ <i class="el-icon-office-building"></i>
|
|
|
+ <span>经编车间温度探头</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8" v-for="n in 6" :key="n">
|
|
|
+ <div class="probe-item">
|
|
|
+ <div class="probe-name">探头{{ n }}</div>
|
|
|
+ <div class="probe-value">{{ getRandomValue('18-25') }} ℃</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card class="system-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="system-header">
|
|
|
+ <i class="el-icon-office-building"></i>
|
|
|
+ <span>成品车间温度探头</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="6" v-for="n in 4" :key="n">
|
|
|
+ <div class="probe-item">
|
|
|
+ <div class="probe-name">探头{{ n }}</div>
|
|
|
+ <div class="probe-value">{{ getRandomValue('18-25') }} ℃</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|
|
+
|
|
|
+// 热水系统数据
|
|
|
+const hotWaterSystem = ref([
|
|
|
+ { id: 1, name: '换热水箱当前温度', range: '60-75', unit: '℃' },
|
|
|
+ { id: 2, name: '换热水箱当前水位', range: '1-1.4', unit: 'm' },
|
|
|
+ { id: 3, name: '热水循环泵', range: '40-50', unit: 'Hz' },
|
|
|
+ { id: 4, name: '热水出口流量统计', range: '400-500', unit: 'm³/h' }
|
|
|
+])
|
|
|
+
|
|
|
+// 定时器
|
|
|
+let timer = null
|
|
|
+
|
|
|
+// 获取指定范围内的随机值
|
|
|
+const getRandomValue = (range) => {
|
|
|
+ const [min, max] = range.split('-').map(Number)
|
|
|
+ return (Math.random() * (max - min) + min).toFixed(2)
|
|
|
+}
|
|
|
+
|
|
|
+// 根据数值判断状态类
|
|
|
+const getValueClass = (item) => {
|
|
|
+ const [min, max] = item.range.split('-').map(Number)
|
|
|
+ const currentValue = parseFloat(getRandomValue(item.range))
|
|
|
+
|
|
|
+ if (currentValue >= min && currentValue <= max) {
|
|
|
+ return 'normal'
|
|
|
+ } else if (currentValue < min) {
|
|
|
+ return 'low'
|
|
|
+ } else {
|
|
|
+ return 'high'
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 开始定时刷新数据
|
|
|
+const startRefresh = () => {
|
|
|
+ timer = setInterval(() => {
|
|
|
+ // 触发视图更新
|
|
|
+ }, 5000) // 每5秒刷新一次
|
|
|
+}
|
|
|
+
|
|
|
+// 清理定时器
|
|
|
+onMounted(() => {
|
|
|
+ startRefresh()
|
|
|
+})
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ if (timer) {
|
|
|
+ clearInterval(timer)
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.hot-monitor-container {
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ min-height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.header-section {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.page-title {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #2c3e50;
|
|
|
+ margin: 0;
|
|
|
+ background: linear-gradient(45deg, #667eea, #764ba2);
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+ background-clip: text;
|
|
|
+}
|
|
|
+
|
|
|
+.dashboard-container {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.system-card {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ border-radius: 10px;
|
|
|
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
|
|
+ border: none;
|
|
|
+ background: #ffffff;
|
|
|
+
|
|
|
+ :deep(.el-card__header) {
|
|
|
+ background: linear-gradient(90deg, #f8f9fa, #e9ecef);
|
|
|
+ padding: 15px 20px;
|
|
|
+ border-bottom: 1px solid #e1e4e8;
|
|
|
+ border-radius: 10px 10px 0 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.system-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2c3e50;
|
|
|
+
|
|
|
+ i {
|
|
|
+ margin-right: 10px;
|
|
|
+ font-size: 22px;
|
|
|
+ color: #3498db;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.data-item {
|
|
|
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 20px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ border: 1px solid #dee2e6;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
|
|
|
+ transform: translateY(-3px);
|
|
|
+ background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.item-label {
|
|
|
+ font-size: 15px;
|
|
|
+ color: #495057;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.item-value {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: 700;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
+
|
|
|
+ &.normal {
|
|
|
+ color: #27ae60;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.low {
|
|
|
+ color: #3498db;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.high {
|
|
|
+ color: #e74c3c;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.item-range {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #6c757d;
|
|
|
+ font-style: italic;
|
|
|
+}
|
|
|
+
|
|
|
+.temperature-section {
|
|
|
+ margin-top: 25px;
|
|
|
+}
|
|
|
+
|
|
|
+.probe-item {
|
|
|
+ background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 15px 10px;
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ border: 1px solid #90caf9;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ box-shadow: 0 2px 6px rgba(52, 152, 219, 0.2);
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #bbdefb 0%, #90caf9 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);
|
|
|
+ transform: scale(1.05);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.probe-name {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #2c3e50;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.probe-value {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #1a237e;
|
|
|
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+// 响应式设计
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .hot-monitor-container {
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page-title {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-item {
|
|
|
+ padding: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-value {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .probe-item {
|
|
|
+ padding: 12px 6px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .probe-value {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .system-header {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|