From c2f399f2c085a1ce803059c2e8c6399b6d077dd2 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 13 八月 2025 17:55:34 +0800
Subject: [PATCH] 完成能源驾驶舱

---
 src/views/energyManagement/energyCockpit/index.vue | 1380 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,380 insertions(+), 0 deletions(-)

diff --git a/src/views/energyManagement/energyCockpit/index.vue b/src/views/energyManagement/energyCockpit/index.vue
new file mode 100644
index 0000000..9281e37
--- /dev/null
+++ b/src/views/energyManagement/energyCockpit/index.vue
@@ -0,0 +1,1380 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <h2>鑳芥簮椹鹃┒鑸�</h2>
+      <div class="header-info">
+        <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
+        <el-button type="primary" size="small" @click="refreshData">
+          <el-icon><Refresh /></el-icon>
+          鍒锋柊鏁版嵁
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 瀹炴椂鑳借�楃洃鎺� -->
+    <div class="real-time-monitor">
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>鐢靛姏娑堣��</span>
+                <el-tag type="success" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ electricityConsumption }}</span>
+                <span class="unit">kW路h</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(electricityTrend)" size="small">
+                  {{ electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(electricityTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>姘存秷鑰�</span>
+                <el-tag type="primary" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ waterConsumption }}</span>
+                <span class="unit">m鲁</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(waterTrend)" size="small">
+                  {{ waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(waterTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>姘斾綋娑堣��</span>
+                <el-tag type="warning" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ gasConsumption }}</span>
+                <span class="unit">m鲁</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(gasTrend)" size="small">
+                  {{ gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(gasTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 鑳借�楄秼鍔垮垎鏋� -->
+    <div class="trend-analysis">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>鑳借�楄秼鍔垮垎鏋�</span>
+            <div class="time-selector">
+              <el-radio-group v-model="trendTimeUnit" @change="handleTrendTimeChange">
+                <el-radio value="hour">灏忔椂</el-radio>
+                <el-radio value="day">鏃�</el-radio>
+                <el-radio value="week">鍛�</el-radio>
+                <el-radio value="month">鏈�</el-radio>
+                <el-radio value="year">骞�</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+        </template>
+        <div class="chart-container">
+          <div ref="trendChart" style="width: 100%; height: 400px;"></div>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 鑳借�楃粺璁′笌鎺掑悕 -->
+    <div class="statistics-ranking">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card class="statistics-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鑳借�楃粺璁℃姤琛�</span>
+                <div class="header-actions">
+                  <el-select v-model="statisticsPeriod" @change="handleStatisticsChange" size="small" style="width: 100px;">
+                    <el-option label="鏃ョ粺璁�" value="day" />
+                    <el-option label="鍛ㄧ粺璁�" value="week" />
+                    <el-option label="鏈堢粺璁�" value="month" />
+                    <el-option label="骞寸粺璁�" value="year" />
+                  </el-select>
+                </div>
+              </div>
+            </template>
+            <div class="statistics-content">
+              <div class="statistics-item">
+                <span class="label">鎬昏兘鑰楋細</span>
+                <span class="value">{{ totalEnergyConsumption }} kW路h</span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鍚屾瘮锛�</span>
+                <span class="value" :class="getComparisonClass(yearOverYear)">
+                  {{ yearOverYear > 0 ? '+' : '' }}{{ yearOverYear }}%
+                </span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鐜瘮锛�</span>
+                <span class="value" :class="getComparisonClass(monthOverMonth)">
+                  {{ monthOverMonth > 0 ? '+' : '' }}{{ monthOverMonth }}%
+                </span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鑺傝兘鐜囷細</span>
+                <span class="value success">{{ energySavingRate }}%</span>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card class="ranking-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鑳借�楁帓鍚�</span>
+                <el-select v-model="rankingType" @change="handleRankingChange" size="small" style="width: 120px;">
+                  <el-option label="閮ㄩ棬鎺掑悕" value="department" />
+                  <el-option label="杞﹂棿鎺掑悕" value="workshop" />
+                  <el-option label="璁惧鎺掑悕" value="equipment" />
+                </el-select>
+              </div>
+            </template>
+            <div class="ranking-list">
+              <div v-for="(item, index) in rankingList" :key="index" class="ranking-item">
+                <div class="ranking-number" :class="getRankingClass(index + 1)">{{ index + 1 }}</div>
+                <div class="ranking-info">
+                  <div class="ranking-name">{{ item.name }}</div>
+                  <div class="ranking-value">{{ item.value }} kW路h</div>
+                </div>
+                <div class="ranking-trend">
+                  <el-tag :type="getTrendType(item.trend)" size="small">
+                    {{ item.trend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(item.trend) }}%
+                  </el-tag>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 寮傚父鍒嗘瀽涓庢櫤鑳芥帶鍒� -->
+    <div class="analysis-control">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card class="abnormal-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">寮傚父鍒嗘瀽</span>
+                <el-tag type="danger" size="small">{{ abnormalCount }}涓紓甯�</el-tag>
+              </div>
+            </template>
+            <div class="abnormal-list">
+              <div v-for="(item, index) in abnormalList" :key="index" class="abnormal-item">
+                <div class="abnormal-icon">
+                  <el-icon :color="getAbnormalColor(item.level)">
+                    <Warning v-if="item.level === 'warning'" />
+                    <CircleClose v-else />
+                  </el-icon>
+                </div>
+                <div class="abnormal-content">
+                  <div class="abnormal-title">{{ item.title }}</div>
+                  <div class="abnormal-desc">{{ item.description }}</div>
+                  <div class="abnormal-time">{{ item.time }}</div>
+                </div>
+                <div class="abnormal-action">
+                  <el-button link size="small" @click="handleAbnormal(item)">澶勭悊</el-button>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card class="control-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鏅鸿兘鎺у埗绯荤粺</span>
+                <el-switch v-model="autoControlEnabled" @change="handleAutoControlChange" />
+              </div>
+            </template>
+            <div class="control-content">
+              <div class="control-item">
+                <span class="label">宄拌胺骞崇數浠风鐞嗭細</span>
+                <el-tag :type="getPriceType(currentPriceType)" size="small">
+                  {{ getPriceTypeText(currentPriceType) }}
+                </el-tag>
+              </div>
+              <div class="control-item">
+                <span class="label">璐熻嵎棰勬祴锛�</span>
+                <span class="value">{{ loadForecast }} kW</span>
+              </div>
+              <div class="control-item">
+                <span class="label">鑷姩鍚仠锛�</span>
+                <el-tag :type="autoStartStop ? 'success' : 'info'" size="small">
+                  {{ autoStartStop ? '宸插惎鐢�' : '宸茬鐢�' }}
+                </el-tag>
+              </div>
+              <div class="control-item">
+                <span class="label">鏅鸿兘璋冭妭锛�</span>
+                <el-progress :percentage="intelligentAdjustment" :color="getProgressColor" />
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 鐜繚鎸囨爣 -->
+    <div class="environmental-indicators">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>鐜繚鎸囨爣鐩戞帶</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">纰虫帓鏀鹃噺</div>
+              <div class="indicator-value">{{ carbonEmission }} kg</div>
+              <div class="indicator-trend">
+                <span>鍚屾瘮锛�</span>
+                <span :class="getComparisonClass(carbonEmissionTrend)">
+                  {{ carbonEmissionTrend > 0 ? '+' : '' }}{{ carbonEmissionTrend }}%
+                </span>
+              </div>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">鐜繚杈炬爣鐜�</div>
+              <div class="indicator-value">{{ environmentalCompliance }}%</div>
+              <div class="indicator-trend">
+                <span>鐩爣锛�</span>
+                <span class="success">95%</span>
+              </div>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">缁胯壊鑳芥簮鍗犳瘮</div>
+              <div class="indicator-value">{{ greenEnergyRatio }}%</div>
+              <div class="indicator-trend">
+                <span>鐩爣锛�</span>
+                <span class="success">30%</span>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </el-card>
+    </div>
+
+    <!-- 澶氱淮搴︽姤琛� -->
+    <div class="multi-dimensional-reports">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>澶氱淮搴︽姤琛�</span>
+          </div>
+        </template>
+        <div class="report-filters">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <el-form-item label="鏃堕棿缁村害">
+                <el-select v-model="reportTimeDimension" placeholder="閫夋嫨鏃堕棿缁村害">
+                  <el-option label="灏忔椂" value="hour" />
+                  <el-option label="鏃�" value="day" />
+                  <el-option label="鍛�" value="week" />
+                  <el-option label="鏈�" value="month" />
+                  <el-option label="骞�" value="year" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="閮ㄩ棬缁村害">
+                <el-select v-model="reportDepartmentDimension" placeholder="閫夋嫨閮ㄩ棬">
+                  <el-option label="鍏ㄩ儴閮ㄩ棬" value="all" />
+                  <el-option label="鐢熶骇閮�" value="production" />
+                  <el-option label="鎶�鏈儴" value="technology" />
+                  <el-option label="琛屾斂閮�" value="administration" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="璁惧缁村害">
+                <el-select v-model="reportEquipmentDimension" placeholder="閫夋嫨璁惧绫诲瀷">
+                  <el-option label="鍏ㄩ儴璁惧" value="all" />
+                  <el-option label="鐢靛姏璁惧" value="electricity" />
+                  <el-option label="姘村鐞嗚澶�" value="water" />
+                  <el-option label="姘斾綋璁惧" value="gas" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item>
+                <el-button type="primary" @click="generateReport">鐢熸垚鎶ヨ〃</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+        <div class="report-preview">
+          <div class="report-data">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">鐢靛姏娑堣��</div>
+                  <div class="data-value">{{ reportData.electricity }} kW路h</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.electricityTrend)">
+                      {{ reportData.electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.electricityTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">姘存秷鑰�</div>
+                  <div class="data-value">{{ reportData.water }} m鲁</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.waterTrend)">
+                      {{ reportData.waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.waterTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">姘斾綋娑堣��</div>
+                  <div class="data-value">{{ reportData.gas }} m鲁</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.gasTrend)">
+                      {{ reportData.gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.gasTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+            
+            <div class="report-chart">
+              <div class="chart-title">鑳借�楄秼鍔垮浘</div>
+              <div class="chart-bars">
+                <div v-for="(item, index) in reportData.chartData" :key="index" class="chart-bar">
+                  <div class="bar-label">{{ item.label }}</div>
+                  <div class="bar-container">
+                    <div class="bar-fill" :style="{ height: item.percentage + '%', backgroundColor: item.color }"></div>
+                  </div>
+                  <div class="bar-value">{{ item.value }}</div>
+                </div>
+              </div>
+            </div>
+            
+            <div class="report-summary">
+              <div class="summary-item">
+                <span class="summary-label">鎬昏兘鑰楋細</span>
+                <span class="summary-value">{{ reportData.totalEnergy }} kW路h</span>
+              </div>
+              <div class="summary-item">
+                <span class="summary-label">骞冲潎鑳借�楋細</span>
+                <span class="summary-value">{{ reportData.averageEnergy }} kW路h</span>
+              </div>
+              <div class="summary-item">
+                <span class="summary-label">鑳借�楁晥鐜囷細</span>
+                <span class="summary-value">{{ reportData.efficiency }}%</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import * as echarts from 'echarts'
+import { 
+  Refresh, 
+  Download, 
+  Warning, 
+  CircleClose, 
+  Document, 
+  Edit, 
+  Bell
+} from '@element-plus/icons-vue'
+
+// 鍝嶅簲寮忔暟鎹�
+const lastUpdateTime = ref('')
+const electricityConsumption = ref(0)
+const waterConsumption = ref(0)
+const gasConsumption = ref(0)
+const electricityTrend = ref(0)
+const waterTrend = ref(0)
+const gasTrend = ref(0)
+
+// 瓒嬪娍鍒嗘瀽
+const trendTimeUnit = ref('day')
+const trendChart = ref(null)
+let chartInstance = null
+
+// 缁熻鎶ヨ〃
+const statisticsPeriod = ref('month')
+const totalEnergyConsumption = ref(0)
+const yearOverYear = ref(0)
+const monthOverMonth = ref(0)
+const energySavingRate = ref(0)
+
+// 鑳借�楁帓鍚�
+const rankingType = ref('department')
+const rankingList = ref([])
+
+// 寮傚父鍒嗘瀽
+const abnormalCount = ref(0)
+const abnormalList = ref([])
+
+// 鏅鸿兘鎺у埗
+const autoControlEnabled = ref(true)
+const currentPriceType = ref('peak')
+const loadForecast = ref(0)
+const autoStartStop = ref(true)
+const intelligentAdjustment = ref(0)
+
+// 鐜繚鎸囨爣
+const carbonEmission = ref(0)
+const carbonEmissionTrend = ref(0)
+const environmentalCompliance = ref(0)
+const greenEnergyRatio = ref(0)
+
+// 澶氱淮搴︽姤琛�
+const reportTimeDimension = ref('month')
+const reportDepartmentDimension = ref('all')
+const reportEquipmentDimension = ref('all')
+const reportData = ref({
+  electricity: 0,
+  water: 0,
+  gas: 0,
+  electricityTrend: 0,
+  waterTrend: 0,
+  gasTrend: 0,
+  totalEnergy: 0,
+  averageEnergy: 0,
+  efficiency: 0,
+  chartData: []
+})
+
+// 瀹氭椂鍣�
+let updateTimer = null
+
+// 鑾峰彇瓒嬪娍绫诲瀷鏍峰紡
+const getTrendType = (trend) => {
+  if (trend > 0) return 'danger'
+  if (trend < 0) return 'success'
+  return 'info'
+}
+
+// 鑾峰彇瀵规瘮绫诲瀷鏍峰紡
+const getComparisonClass = (value) => {
+  if (value > 0) return 'danger'
+  if (value < 0) return 'success'
+  return 'info'
+}
+
+// 鑾峰彇鎺掑悕鏍峰紡
+const getRankingClass = (rank) => {
+  if (rank === 1) return 'ranking-first'
+  if (rank === 2) return 'ranking-second'
+  if (rank === 3) return 'ranking-third'
+  return 'ranking-normal'
+}
+
+// 鑾峰彇寮傚父棰滆壊
+const getAbnormalColor = (level) => {
+  return level === 'warning' ? '#E6A23C' : '#F56C6C'
+}
+
+// 鑾峰彇鐢典环绫诲瀷鏍峰紡
+const getPriceType = (type) => {
+  const typeMap = {
+    peak: 'danger',
+    normal: 'warning',
+    valley: 'success'
+  }
+  return typeMap[type] || 'info'
+}
+
+// 鑾峰彇鐢典环绫诲瀷鏂囨湰
+const getPriceTypeText = (type) => {
+  const typeMap = {
+    peak: '宄版椂',
+    normal: '骞虫椂',
+    valley: '璋锋椂'
+  }
+  return typeMap[type] || '鏈煡'
+}
+
+// 鑾峰彇杩涘害鏉¢鑹�
+const getProgressColor = (percentage) => {
+  if (percentage < 50) return '#67C23A'
+  if (percentage < 80) return '#E6A23C'
+  return '#F56C6C'
+}
+
+// 鑾峰彇瓒嬪娍鏍峰紡
+const getTrendClass = (trend) => {
+  if (trend > 0) return 'trend-up'
+  if (trend < 0) return 'trend-down'
+  return 'trend-stable'
+}
+
+// 妯℃嫙鏁版嵁鐢熸垚
+const generateMockData = () => {
+  // 瀹炴椂鑳借�楁暟鎹�
+  electricityConsumption.value = Math.floor(Math.random() * 1000) + 2000
+  waterConsumption.value = Math.floor(Math.random() * 100) + 150
+  gasConsumption.value = Math.floor(Math.random() * 50) + 80
+  
+  // 瓒嬪娍鏁版嵁
+  electricityTrend.value = (Math.random() * 20 - 10).toFixed(1)
+  waterTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
+  gasTrend.value = (Math.random() * 12 - 6).toFixed(1)
+  
+  // 缁熻鏁版嵁
+  totalEnergyConsumption.value = Math.floor(Math.random() * 50000) + 100000
+  yearOverYear.value = (Math.random() * 20 - 10).toFixed(1)
+  monthOverMonth.value = (Math.random() * 15 - 7.5).toFixed(1)
+  energySavingRate.value = (Math.random() * 10 + 5).toFixed(1)
+  
+  // 鎺掑悕鏁版嵁
+  rankingList.value = [
+    { name: '鐢熶骇杞﹂棿A', value: Math.floor(Math.random() * 5000) + 10000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鐢熶骇杞﹂棿B', value: Math.floor(Math.random() * 4000) + 8000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鎶�鏈爺鍙戦儴', value: Math.floor(Math.random() * 3000) + 6000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '琛屾斂鍔炲叕鍖�', value: Math.floor(Math.random() * 2000) + 4000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鍚庡嫟淇濋殰鍖�', value: Math.floor(Math.random() * 1500) + 3000, trend: (Math.random() * 20 - 10).toFixed(1) }
+  ].sort((a, b) => b.value - a.value)
+  
+  // 寮傚父鏁版嵁
+  abnormalCount.value = Math.floor(Math.random() * 5) + 1
+  abnormalList.value = [
+    { level: 'warning', title: '鐢靛姏璐熻嵎杩囬珮', description: '鐢熶骇杞﹂棿A鐢靛姏璐熻嵎杈惧埌85%锛屽缓璁鏌ヨ澶囪繍琛岀姸鎬�', time: '2鍒嗛挓鍓�' },
+    { level: 'error', title: '姘村帇寮傚父', description: '姘村鐞嗚澶囧帇鍔涘紓甯革紝褰撳墠鍘嬪姏0.3MPa锛屼綆浜庢甯歌寖鍥�', time: '5鍒嗛挓鍓�' }
+  ]
+  
+  // 鏅鸿兘鎺у埗鏁版嵁
+  loadForecast.value = Math.floor(Math.random() * 500) + 1500
+  intelligentAdjustment.value = Math.floor(Math.random() * 30) + 60
+  
+  // 鐜繚鎸囨爣
+  carbonEmission.value = Math.floor(Math.random() * 1000) + 5000
+  carbonEmissionTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
+  environmentalCompliance.value = (Math.random() * 5 + 95).toFixed(1)
+  greenEnergyRatio.value = (Math.random() * 10 + 25).toFixed(1)
+  
+  // 鏇存柊鏈�鍚庢洿鏂版椂闂�
+  lastUpdateTime.value = new Date().toLocaleString()
+  
+  // 鍚屾椂鏇存柊鎶ヨ〃鏁版嵁
+  generateReportData()
+}
+
+// 鍒濆鍖栬秼鍔垮浘琛�
+const initTrendChart = () => {
+  if (chartInstance) {
+    chartInstance.dispose()
+  }
+  
+  chartInstance = echarts.init(trendChart.value)
+  
+  const option = {
+    title: {
+      text: '鑳借�楄秼鍔垮垎鏋�',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'axis'
+    },
+    legend: {
+      data: ['鐢靛姏', '姘�', '姘斾綋'],
+      bottom: 10
+    },
+    xAxis: {
+      type: 'category',
+      data: generateTimeData()
+    },
+    yAxis: {
+      type: 'value',
+      name: '娑堣�楅噺'
+    },
+    series: [
+      {
+        name: '鐢靛姏',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      },
+      {
+        name: '姘�',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      },
+      {
+        name: '姘斾綋',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      }
+    ]
+  }
+  
+  chartInstance.setOption(option)
+}
+
+// 鐢熸垚鏃堕棿鏁版嵁
+const generateTimeData = () => {
+  const data = []
+  const now = new Date()
+  
+  switch (trendTimeUnit.value) {
+    case 'hour':
+      for (let i = 23; i >= 0; i--) {
+        const time = new Date(now.getTime() - i * 60 * 60 * 1000)
+        data.unshift(time.getHours() + ':00')
+      }
+      break
+    case 'day':
+      for (let i = 29; i >= 0; i--) {
+        const time = new Date(now.getTime() - i * 24 * 60 * 60 * 1000)
+        data.unshift(time.getDate() + '鏃�')
+      }
+      break
+    case 'week':
+      for (let i = 11; i >= 0; i--) {
+        data.unshift(`绗�${12 - i}鍛╜)
+      }
+      break
+    case 'month':
+      for (let i = 11; i >= 0; i--) {
+        const month = (12 - i) % 12 || 12
+        data.unshift(`${month}鏈坄)
+      }
+      break
+    case 'year':
+      for (let i = 4; i >= 0; i--) {
+        const year = new Date().getFullYear() - i
+        data.unshift(`${year}骞碻)
+      }
+      break
+  }
+  
+  return data
+}
+
+// 鐢熸垚绯诲垪鏁版嵁
+const generateSeriesData = () => {
+  const data = []
+  const count = trendTimeUnit.value === 'hour' ? 24 : 
+                trendTimeUnit.value === 'day' ? 30 : 
+                trendTimeUnit.value === 'week' ? 12 : 
+                trendTimeUnit.value === 'month' ? 12 : 5
+  
+  for (let i = 0; i < count; i++) {
+    data.push(Math.floor(Math.random() * 1000) + 500)
+  }
+  
+  return data
+}
+
+// 澶勭悊瓒嬪娍鏃堕棿鍙樺寲
+const handleTrendTimeChange = () => {
+  nextTick(() => {
+    initTrendChart()
+  })
+}
+
+// 澶勭悊缁熻鍛ㄦ湡鍙樺寲
+const handleStatisticsChange = () => {
+  generateMockData()
+}
+
+// 澶勭悊鎺掑悕绫诲瀷鍙樺寲
+const handleRankingChange = () => {
+  // 鏍规嵁绫诲瀷閲嶆柊鐢熸垚鎺掑悕鏁版嵁
+  generateMockData()
+}
+
+// 澶勭悊鑷姩鎺у埗鍙樺寲
+const handleAutoControlChange = (value) => {
+  ElMessage.success(`鏅鸿兘鎺у埗绯荤粺宸�${value ? '鍚敤' : '绂佺敤'}`)
+}
+
+// 澶勭悊寮傚父
+const handleAbnormal = (item) => {
+  ElMessage.info(`姝e湪澶勭悊寮傚父锛�${item.title}`)
+}
+
+// 鍒锋柊鏁版嵁
+const refreshData = () => {
+  generateMockData()
+  if (chartInstance) {
+    initTrendChart()
+  }
+  ElMessage.success('鏁版嵁宸插埛鏂�')
+}
+
+// 瀵煎嚭缁熻
+const exportStatistics = () => {
+  ElMessage.success('缁熻鏁版嵁瀵煎嚭鎴愬姛')
+}
+
+// 瀵煎嚭鐜繚鎶ュ憡
+const exportEnvironmentalReport = () => {
+  ElMessage.success('鐜繚鎶ュ憡瀵煎嚭鎴愬姛')
+}
+
+// 鐢熸垚鑷畾涔夋姤琛�
+const generateCustomReport = () => {
+  ElMessage.info('鑷畾涔夋姤琛ㄥ姛鑳藉紑鍙戜腑...')
+}
+
+// 璁㈤槄鎶ヨ〃
+const subscribeReport = () => {
+  ElMessage.info('鎶ヨ〃璁㈤槄鍔熻兘寮�鍙戜腑...')
+}
+
+// 鐢熸垚鎶ヨ〃鏁版嵁
+const generateReportData = () => {
+  // 鐢熸垚鍩虹鏁版嵁
+  reportData.value.electricity = Math.floor(Math.random() * 5000) + 8000
+  reportData.value.water = Math.floor(Math.random() * 200) + 300
+  reportData.value.gas = Math.floor(Math.random() * 100) + 150
+  
+  // 鐢熸垚瓒嬪娍鏁版嵁
+  reportData.value.electricityTrend = (Math.random() * 20 - 10).toFixed(1)
+  reportData.value.waterTrend = (Math.random() * 15 - 7.5).toFixed(1)
+  reportData.value.gasTrend = (Math.random() * 12 - 6).toFixed(1)
+  
+  // 璁$畻鎬昏兘鑰楀拰骞冲潎鑳借��
+  reportData.value.totalEnergy = reportData.value.electricity + reportData.value.water * 0.1 + reportData.value.gas * 0.05
+  reportData.value.averageEnergy = Math.floor(reportData.value.totalEnergy / 3)
+  reportData.value.efficiency = (Math.random() * 20 + 80).toFixed(1)
+  
+  // 鐢熸垚鍥捐〃鏁版嵁
+  const labels = ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩']
+  const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399', '#9c27b0', '#ff9800']
+  
+  reportData.value.chartData = labels.map((label, index) => ({
+    label,
+    value: Math.floor(Math.random() * 1000) + 500,
+    percentage: Math.floor(Math.random() * 40) + 30,
+    color: colors[index]
+  }))
+}
+
+// 鐢熸垚鎶ヨ〃
+const generateReport = () => {
+  generateReportData()
+  ElMessage.success('鎶ヨ〃鐢熸垚鎴愬姛')
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// 鍚姩瀹氭椂鏇存柊
+const startAutoUpdate = () => {
+  updateTimer = setInterval(() => {
+    generateMockData()
+    if (chartInstance) {
+      initTrendChart()
+    }
+  }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
+}
+
+// 鍋滄瀹氭椂鏇存柊
+const stopAutoUpdate = () => {
+  if (updateTimer) {
+    clearInterval(updateTimer)
+    updateTimer = null
+  }
+}
+
+// 缁勪欢鎸傝浇
+onMounted(() => {
+  generateMockData()
+  nextTick(() => {
+    initTrendChart()
+  })
+  startAutoUpdate()
+})
+
+// 缁勪欢鍗歌浇
+onUnmounted(() => {
+  stopAutoUpdate()
+  if (chartInstance) {
+    chartInstance.dispose()
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 12px;
+  background: #f5f5f5;
+  min-height: 100vh;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  padding: 16px;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+  h2 {
+    margin: 0;
+    color: #303133;
+    font-size: 22px;
+  }
+
+  .header-info {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+
+    .update-time {
+      color: #909399;
+      font-size: 14px;
+    }
+  }
+}
+
+.real-time-monitor {
+  margin-bottom: 12px;
+
+  .monitor-card {
+    .monitor-content {
+      text-align: center;
+      padding: 16px 0;
+
+      .monitor-value {
+        margin-bottom: 12px;
+
+        .value {
+          font-size: 28px;
+          font-weight: bold;
+          color: #409eff;
+        }
+
+        .unit {
+          font-size: 14px;
+          color: #909399;
+          margin-left: 4px;
+        }
+      }
+
+      .monitor-trend {
+        .trend-label {
+          font-size: 14px;
+          color: #606266;
+          margin-right: 6px;
+        }
+      }
+    }
+  }
+}
+
+.trend-analysis {
+  margin-bottom: 12px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .time-selector {
+      .el-radio-group {
+        .el-radio {
+          margin-right: 4px;
+        }
+      }
+    }
+  }
+
+  .chart-container {
+    padding: 16px 0;
+  }
+}
+
+.statistics-ranking {
+  margin-bottom: 12px;
+
+  .statistics-card, .ranking-card {
+    height: 100%;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+    border-radius: 8px;
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+    }
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 12px 16px;
+    border-bottom: 1px solid #f0f0f0;
+    background: #fafafa;
+
+    .card-title {
+      font-size: 15px;
+      font-weight: 600;
+      color: #303133;
+    }
+
+    .header-actions {
+      display: flex;
+      gap: 8px;
+      align-items: center;
+    }
+  }
+
+  .statistics-content {
+    padding: 16px;
+
+    .statistics-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 12px;
+      padding: 10px 12px;
+      background: #f8f9fa;
+      border-radius: 6px;
+      transition: background-color 0.3s ease;
+
+      &:hover {
+        background: #e9ecef;
+      }
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        color: #606266;
+        font-size: 14px;
+        font-weight: 500;
+      }
+
+      .value {
+        font-weight: bold;
+        font-size: 15px;
+
+        &.success {
+          color: #67c23a;
+        }
+      }
+    }
+  }
+
+  .ranking-list {
+    padding: 16px;
+
+    .ranking-item {
+      display: flex;
+      align-items: center;
+      padding: 12px;
+      margin-bottom: 6px;
+      background: #f8f9fa;
+      border-radius: 6px;
+      transition: all 0.3s ease;
+
+      &:hover {
+        background: #e9ecef;
+        transform: translateX(4px);
+      }
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .ranking-number {
+        width: 32px;
+        height: 32px;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-weight: bold;
+        font-size: 14px;
+        margin-right: 12px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+        &.ranking-first {
+          background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
+          color: #fff;
+        }
+
+        &.ranking-second {
+          background: linear-gradient(135deg, #c0c0c0 0%, #d4d4d4 100%);
+          color: #fff;
+        }
+
+        &.ranking-third {
+          background: linear-gradient(135deg, #cd7f32 0%, #daa520 100%);
+          color: #fff;
+        }
+
+        &.ranking-normal {
+          background: linear-gradient(135deg, #f5f5f5 0%, #e9ecef 100%);
+          color: #909399;
+        }
+      }
+
+      .ranking-info {
+        flex: 1;
+
+        .ranking-name {
+          font-weight: 600;
+          color: #303133;
+          margin-bottom: 4px;
+          font-size: 14px;
+        }
+
+        .ranking-value {
+          color: #606266;
+          font-size: 13px;
+          font-weight: 500;
+        }
+      }
+
+      .ranking-trend {
+        margin-left: 12px;
+      }
+    }
+  }
+}
+
+.analysis-control {
+  margin-bottom: 20px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .abnormal-list {
+    .abnormal-item {
+      display: flex;
+      align-items: flex-start;
+      padding: 15px 0;
+      border-bottom: 1px solid #f0f0f0;
+
+      &:last-child {
+        border-bottom: none;
+      }
+
+      .abnormal-icon {
+        margin-right: 15px;
+        margin-top: 2px;
+      }
+
+      .abnormal-content {
+        flex: 1;
+
+        .abnormal-title {
+          font-weight: bold;
+          color: #303133;
+          margin-bottom: 5px;
+        }
+
+        .abnormal-desc {
+          color: #606266;
+          font-size: 14px;
+          margin-bottom: 5px;
+        }
+
+        .abnormal-time {
+          color: #909399;
+          font-size: 12px;
+        }
+      }
+
+      .abnormal-action {
+        margin-left: 15px;
+      }
+    }
+  }
+
+  .control-content {
+    .control-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        color: #606266;
+        font-size: 14px;
+      }
+
+      .value {
+        font-weight: bold;
+        color: #303133;
+      }
+    }
+  }
+}
+
+.environmental-indicators {
+  margin-bottom: 20px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .header-actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .indicator-item {
+    text-align: center;
+    padding: 20px 0;
+
+    .indicator-title {
+      color: #606266;
+      font-size: 14px;
+      margin-bottom: 10px;
+    }
+
+    .indicator-value {
+      font-size: 24px;
+      font-weight: bold;
+      color: #409eff;
+      margin-bottom: 10px;
+    }
+
+    .indicator-trend {
+      font-size: 12px;
+      color: #909399;
+
+      .success {
+        color: #67c23a;
+      }
+    }
+  }
+}
+
+.multi-dimensional-reports {
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .header-actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .report-filters {
+    padding: 20px 0;
+    border-bottom: 1px solid #f0f0f0;
+    margin-bottom: 20px;
+  }
+
+  .report-preview {
+    .report-data {
+      padding: 20px 0;
+
+      .data-card {
+        text-align: center;
+        padding: 16px;
+        background: #f8f9fa;
+        border-radius: 8px;
+        margin-bottom: 16px;
+
+        .data-title {
+          color: #606266;
+          font-size: 14px;
+          margin-bottom: 8px;
+        }
+
+        .data-value {
+          font-size: 20px;
+          font-weight: bold;
+          color: #303133;
+          margin-bottom: 8px;
+        }
+
+        .data-trend {
+          font-size: 12px;
+
+          .trend-up {
+            color: #f56c6c;
+          }
+
+          .trend-down {
+            color: #67c23a;
+          }
+
+          .trend-stable {
+            color: #909399;
+          }
+        }
+      }
+
+      .report-chart {
+        margin: 20px 0;
+        padding: 20px;
+        background: #f8f9fa;
+        border-radius: 8px;
+
+        .chart-title {
+          text-align: center;
+          font-size: 16px;
+          font-weight: 600;
+          color: #303133;
+          margin-bottom: 16px;
+        }
+
+        .chart-bars {
+          display: flex;
+          justify-content: space-around;
+          align-items: flex-end;
+          height: 120px;
+
+          .chart-bar {
+            text-align: center;
+            flex: 1;
+            margin: 0 8px;
+
+            .bar-label {
+              font-size: 12px;
+              color: #606266;
+              margin-bottom: 8px;
+            }
+
+            .bar-container {
+              height: 80px;
+              background: #e9ecef;
+              border-radius: 4px;
+              position: relative;
+              margin-bottom: 8px;
+            }
+
+            .bar-fill {
+              position: absolute;
+              bottom: 0;
+              left: 0;
+              right: 0;
+              border-radius: 4px;
+              transition: height 0.3s ease;
+            }
+
+            .bar-value {
+              font-size: 12px;
+              color: #303133;
+              font-weight: 500;
+            }
+          }
+        }
+      }
+
+      .report-summary {
+        display: flex;
+        justify-content: space-around;
+        padding: 20px;
+        background: #f8f9fa;
+        border-radius: 8px;
+
+        .summary-item {
+          text-align: center;
+
+          .summary-label {
+            display: block;
+            color: #606266;
+            font-size: 14px;
+            margin-bottom: 8px;
+          }
+
+          .summary-value {
+            font-size: 18px;
+            font-weight: bold;
+            color: #303133;
+          }
+        }
+      }
+    }
+  }
+}
+
+// 閫氱敤鏍峰紡
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.success {
+  color: #67c23a;
+}
+
+.danger {
+  color: #f56c6c;
+}
+
+.warning {
+  color: #e6a23c;
+}
+
+.info {
+  color: #909399;
+}
+</style>

--
Gitblit v1.9.3