|
|
@@ -0,0 +1,460 @@
|
|
|
+<template>
|
|
|
+ <div class="water-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="15">
|
|
|
+ <el-col :span="8" v-for="(item, index) in waterSystemData" :key="index">
|
|
|
+ <div class="data-item" :class="getItemClass(item)">
|
|
|
+ <div class="item-label">{{ item.name }}</div>
|
|
|
+ <div class="item-value" :class="getValueClass(item)">
|
|
|
+ {{ item.value !== undefined ? item.value : '-' }} {{ item.unit }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 排放口监测 -->
|
|
|
+ <el-card class="system-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="system-header">
|
|
|
+ <i class="el-icon-water-cup"></i>
|
|
|
+ <span>排放口监测</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-row :gutter="15">
|
|
|
+ <el-col :span="8" v-for="(item, index) in dischargeData" :key="index">
|
|
|
+ <div class="data-item" :class="getItemClass(item)">
|
|
|
+ <div class="item-label">{{ item.name }}</div>
|
|
|
+ <div class="item-value" :class="getValueClass(item)">
|
|
|
+ {{ item.value !== undefined ? item.value : '-' }} {{ item.unit }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, onMounted } from 'vue'
|
|
|
+import { getData } from '@/api/lean/water.js'
|
|
|
+
|
|
|
+// 污水处理系统数据变量定义
|
|
|
+const waterSystemData = ref([
|
|
|
+ {
|
|
|
+ name: '污水站1号总提升累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'lift1',
|
|
|
+ colorClass: 'blue-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站2号总提升累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'lift2',
|
|
|
+ colorClass: 'blue-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站外排总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'discharge',
|
|
|
+ colorClass: 'blue-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站雨水出口总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'rainOut',
|
|
|
+ colorClass: 'cyan-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站雨水进口总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'rainIn',
|
|
|
+ colorClass: 'cyan-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站MBR产水总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'mbr',
|
|
|
+ colorClass: 'green-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站RO产水量总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'ro',
|
|
|
+ colorClass: 'green-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站RO浓水量总累计量',
|
|
|
+ unit: 'm³',
|
|
|
+ value: 0,
|
|
|
+ key: 'roConcentrate',
|
|
|
+ colorClass: 'green-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水站中水回收率百分比',
|
|
|
+ unit: '%',
|
|
|
+ value: 0,
|
|
|
+ key: 'recovery',
|
|
|
+ colorClass: 'purple-theme'
|
|
|
+ }
|
|
|
+])
|
|
|
+
|
|
|
+// 排放口监测数据变量定义
|
|
|
+const dischargeData = ref([
|
|
|
+ {
|
|
|
+ name: '污水排放口COD实际值',
|
|
|
+ unit: 'mg/L',
|
|
|
+ value: 0,
|
|
|
+ key: 'cod',
|
|
|
+ colorClass: 'orange-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水排放口总氮实际值',
|
|
|
+ unit: 'mg/L',
|
|
|
+ value: 0,
|
|
|
+ key: 'nitrogen',
|
|
|
+ colorClass: 'orange-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水排放口氨氮实际值',
|
|
|
+ unit: 'mg/L',
|
|
|
+ value: 0,
|
|
|
+ key: 'ammonia',
|
|
|
+ colorClass: 'orange-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水排放口PH值实际值',
|
|
|
+ unit: '',
|
|
|
+ value: 0,
|
|
|
+ key: 'ph',
|
|
|
+ colorClass: 'yellow-theme'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '污水排放口排放实时流量实际值',
|
|
|
+ unit: 'm³/h',
|
|
|
+ value: 0,
|
|
|
+ key: 'flow',
|
|
|
+ colorClass: 'red-theme'
|
|
|
+ }
|
|
|
+])
|
|
|
+
|
|
|
+// 根据数值判断状态类
|
|
|
+const getValueClass = (item) => {
|
|
|
+ // 简单的状态判断,后续可根据实际业务逻辑调整
|
|
|
+ if (item.value === undefined || item.value === null || item.value === '-') {
|
|
|
+ return 'normal'
|
|
|
+ }
|
|
|
+
|
|
|
+ const currentValue = parseFloat(item.value)
|
|
|
+
|
|
|
+ // 特殊处理PH值范围
|
|
|
+ if (item.name.includes('PH')) {
|
|
|
+ if (currentValue >= 6.5 && currentValue <= 8.5) {
|
|
|
+ return 'normal'
|
|
|
+ } else if (currentValue < 6.5) {
|
|
|
+ return 'low'
|
|
|
+ } else {
|
|
|
+ return 'high'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认正常状态
|
|
|
+ return 'normal'
|
|
|
+}
|
|
|
+
|
|
|
+// 获取项目容器类
|
|
|
+const getItemClass = (item) => {
|
|
|
+ return item.colorClass || 'default-theme'
|
|
|
+}
|
|
|
+
|
|
|
+// 更新所有数据(供后台调用)
|
|
|
+const updateAllData = (newData) => {
|
|
|
+ // 将数组转换为基于key的对象映射
|
|
|
+ const dataMap = {}
|
|
|
+ newData.forEach(item => {
|
|
|
+ dataMap[item.key] = item.value
|
|
|
+ })
|
|
|
+
|
|
|
+ // 更新污水处理系统数据
|
|
|
+ waterSystemData.value = waterSystemData.value.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ value: dataMap[item.key] !== undefined ? dataMap[item.key] : item.value
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 更新排放口监测数据
|
|
|
+ dischargeData.value = dischargeData.value.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ value: dataMap[item.key] !== undefined ? dataMap[item.key] : item.value
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 获取数据
|
|
|
+const fetchData = async () => {
|
|
|
+ try {
|
|
|
+ const response = await getData()
|
|
|
+ const { code, msg, data } = response
|
|
|
+ if (code === 0) { // 根据您提供的数据,code 应该是 0 而不是 200
|
|
|
+ updateAllData(data)
|
|
|
+ } else {
|
|
|
+ console.error('获取数据失败:', msg)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取数据失败:', error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 组件挂载时获取数据
|
|
|
+onMounted(() => {
|
|
|
+ fetchData()
|
|
|
+})
|
|
|
+
|
|
|
+// 暴露给父组件的方法
|
|
|
+defineExpose({
|
|
|
+ updateAllData,
|
|
|
+ fetchData
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.water-monitor-container {
|
|
|
+ padding: 15px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ min-height: 100%;
|
|
|
+ max-width: 1700px;
|
|
|
+ margin: 0 auto;
|
|
|
+}
|
|
|
+
|
|
|
+.header-section {
|
|
|
+ margin-bottom: 15px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.page-title {
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #2c3e50;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.dashboard-container {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.system-card {
|
|
|
+ margin-bottom: 15px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ background: #ffffff;
|
|
|
+
|
|
|
+ :deep(.el-card__header) {
|
|
|
+ background-color: #f8f9fa;
|
|
|
+ padding: 12px 15px;
|
|
|
+ border-bottom: 1px solid #e1e4e8;
|
|
|
+ border-radius: 8px 8px 0 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.system-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #2c3e50;
|
|
|
+
|
|
|
+ i {
|
|
|
+ margin-right: 8px;
|
|
|
+ font-size: 18px;
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.data-item {
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 15px 12px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+
|
|
|
+ &.blue-theme {
|
|
|
+ background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
|
|
|
+ border-color: #90caf9;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #bbdefb 0%, #90caf9 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.cyan-theme {
|
|
|
+ background: linear-gradient(135deg, #e0f7fa 0%, #b2ebf2 100%);
|
|
|
+ border-color: #80deea;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #b2ebf2 0%, #80deea 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 188, 212, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.green-theme {
|
|
|
+ background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
|
|
|
+ border-color: #a5d6a7;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #c8e6c9 0%, #a5d6a7 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.purple-theme {
|
|
|
+ background: linear-gradient(135deg, #f3e5f5 0%, #e1bee7 100%);
|
|
|
+ border-color: #ce93d8;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #e1bee7 0%, #ce93d8 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(156, 39, 176, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.orange-theme {
|
|
|
+ background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
|
|
|
+ border-color: #ffcc80;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #ffe0b2 0%, #ffcc80 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(255, 152, 0, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.yellow-theme {
|
|
|
+ background: linear-gradient(135deg, #fffde7 0%, #fff9c4 100%);
|
|
|
+ border-color: #fff59d;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #fff9c4 0%, #fff59d 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(255, 235, 59, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &.red-theme {
|
|
|
+ background: linear-gradient(135deg, #ffebee 0%, #ffcdd2 100%);
|
|
|
+ border-color: #ef9a9a;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: linear-gradient(135deg, #ffcdd2 0%, #ef9a9a 100%);
|
|
|
+ box-shadow: 0 4px 12px rgba(244, 67, 54, 0.3);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.item-label {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #424242;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 1.4;
|
|
|
+}
|
|
|
+
|
|
|
+.item-value {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 0;
|
|
|
+
|
|
|
+ &.normal {
|
|
|
+ color: #2e7d32;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.low {
|
|
|
+ color: #1565c0;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.high {
|
|
|
+ color: #c62828;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 响应式设计
|
|
|
+@media (max-width: 1700px) {
|
|
|
+ .water-monitor-container {
|
|
|
+ padding: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page-title {
|
|
|
+ font-size: 22px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-item {
|
|
|
+ padding: 12px 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-label {
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-value {
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .system-header {
|
|
|
+ font-size: 15px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 1200px) {
|
|
|
+ .el-col-8 {
|
|
|
+ width: 33.333%;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .el-col-8 {
|
|
|
+ width: 50%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .water-monitor-container {
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .page-title {
|
|
|
+ font-size: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .data-item {
|
|
|
+ padding: 10px 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-label {
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-value {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|