From 33e6e77746eaea0fc06adb9b359b02e355887061 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 14 八月 2025 11:03:33 +0800
Subject: [PATCH] 完成动态节能

---
 src/views/energyManagement/dynamicEnergySaving/index.vue |  659 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 659 insertions(+), 0 deletions(-)

diff --git a/src/views/energyManagement/dynamicEnergySaving/index.vue b/src/views/energyManagement/dynamicEnergySaving/index.vue
new file mode 100644
index 0000000..eb6f0b1
--- /dev/null
+++ b/src/views/energyManagement/dynamicEnergySaving/index.vue
@@ -0,0 +1,659 @@
+<template>
+  <div class="app-container">
+    <!-- 杈圭紭璁$畻鐘舵�佺洃鎺� -->
+    <el-row :gutter="20" class="status-section">
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><Monitor /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">杈圭紭鏈嶅姟鍣ㄧ姸鎬�</div>
+              <div class="status-value" :class="edgeServerStatus.status">
+                {{ edgeServerStatus.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}
+              </div>
+              <div class="status-detail">鏈�鍚庡績璺�: {{ formatTime(edgeServerStatus.lastHeartbeat) }}</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><Cpu /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">妯″瀷杩愯鐘舵��</div>
+              <div class="status-value" :class="modelStatus.status">
+                {{ modelStatus.status === 'running' ? '杩愯涓�' : '宸插仠姝�' }}
+              </div>
+              <div class="status-detail">杩愯妯″瀷: {{ modelStatus.modelCount }}涓�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><TrendCharts /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">鑺傝兘鏁堟灉</div>
+              <div class="status-value success">{{ energySavingRate.toFixed(1) }}%</div>
+              <div class="status-detail">绱鑺傝兘: {{ totalEnergySaved.toFixed(1) }}kWh</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 娉ㄦ按娉甸鐜囦紭鍖栨帶鍒� -->
+    <el-card class="control-section">
+      <template #header>
+        <span>娉ㄦ按娉甸鐜囦紭鍖栨帶鍒�</span>
+      </template>
+      
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div class="pump-control">
+            <h4>瀹炴椂鍙傛暟鐩戞帶</h4>
+            <el-form label-width="120px">
+              <el-form-item label="鍦板眰鍘嬪姏 (MPa)">
+                <el-input v-model="pumpData.formationPressure" readonly>
+                  <template #append>MPa</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="褰撳墠娉甸�� (Hz)">
+                <el-input v-model="pumpData.currentFrequency" readonly>
+                  <template #append>Hz</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="浼樺寲鍚庢车閫� (Hz)">
+                <el-input v-model="pumpData.optimizedFrequency" readonly>
+                  <template #append>Hz</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="鑳借�楅檷浣�">
+                <el-progress 
+                  :percentage="pumpData.energyReduction" 
+                  :color="getProgressColor"
+                  :format="format => `${format}%`"
+                />
+              </el-form-item>
+              <el-form-item label="娴侀噺 (m鲁/h)">
+                <el-input v-model="pumpData.flowRate" readonly>
+                  <template #append>m鲁/h</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="鍔熺巼 (kW)">
+                <el-input v-model="pumpData.power" readonly>
+                  <template #append>kW</template>
+                </el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+        </el-col>
+        
+        <el-col :span="12">
+          <div class="pump-chart">
+            <h4>棰戠巼浼樺寲瓒嬪娍</h4>
+            <div ref="frequencyChart" style="height: 300px;"></div>
+          </div>
+        </el-col>
+      </el-row>
+      
+      <el-row :gutter="20" class="control-buttons">
+        <el-col :span="24">
+          <el-button 
+            type="primary" 
+            :disabled="!canControl"
+            @click="applyOptimization"
+          >
+            搴旂敤浼樺寲璁剧疆
+          </el-button>
+          <el-button 
+            type="warning" 
+            :disabled="!canControl"
+            @click="emergencyStop"
+          >
+            绱ф�ュ仠姝�
+          </el-button>
+          <el-button 
+            type="info" 
+            @click="showOptimizationHistory"
+          >
+            浼樺寲鍘嗗彶
+          </el-button>
+          <el-button 
+            type="success" 
+            @click="toggleAutoRefresh"
+          >
+            {{ autoRefreshStatus ? '鍋滄鑷姩鍒锋柊' : '寮�鍚嚜鍔ㄥ埛鏂�' }}
+          </el-button>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 杈圭紭璁$畻妯″瀷閰嶇疆 -->
+    <el-card class="model-section">
+      <template #header>
+        <span>杈圭紭璁$畻妯″瀷閰嶇疆</span>
+      </template>
+      
+      <el-table :data="modelConfigs" style="width: 100%">
+        <el-table-column prop="modelName" label="妯″瀷鍚嶇О" />
+        <el-table-column prop="version" label="鐗堟湰" />
+        <el-table-column prop="status" label="鐘舵��">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+              {{ scope.row.status === 'active' ? '婵�娲�' : '寰呮満' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="accuracy" label="鍑嗙‘鐜�" />
+        <el-table-column prop="lastUpdate" label="鏈�鍚庢洿鏂�" />
+        <el-table-column label="鎿嶄綔">
+          <template #default="scope">
+            <el-button 
+              size="small" 
+              @click="updateModel(scope.row)"
+            >
+              鏇存柊妯″瀷
+            </el-button>
+            <el-button 
+              size="small" 
+              type="danger" 
+              @click="deleteModel(scope.row)"
+            >
+              鍒犻櫎
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 鑳借�楀垎鏋愬浘琛� -->
+    <el-card class="analysis-section">
+      <template #header>
+        <span>鑳借�楀垎鏋�</span>
+      </template>
+      
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div ref="energyChart" style="height: 400px;"></div>
+        </el-col>
+        <el-col :span="12">
+          <div ref="savingChart" style="height: 400px;"></div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 浼樺寲鍘嗗彶瀵硅瘽妗� -->
+    <el-dialog v-model="historyDialogVisible" title="浼樺寲鍘嗗彶璁板綍" width="80%">
+      <el-table :data="optimizationHistory" style="width: 100%">
+        <el-table-column prop="timestamp" label="鏃堕棿" />
+        <el-table-column prop="formationPressure" label="鍦板眰鍘嬪姏 (MPa)" />
+        <el-table-column prop="oldFrequency" label="鍘熼鐜� (Hz)" />
+        <el-table-column prop="newFrequency" label="鏂伴鐜� (Hz)" />
+        <el-table-column prop="energySaved" label="鑺傝兘 (kWh)" />
+        <el-table-column prop="status" label="鐘舵��">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'success' ? 'success' : 'warning'">
+              {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, computed } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Monitor, Cpu, TrendCharts } from '@element-plus/icons-vue'
+import * as echarts from 'echarts'
+
+// 鍝嶅簲寮忔暟鎹�
+const edgeServerStatus = ref({ status: 'online', lastHeartbeat: Date.now() })
+const modelStatus = ref({ status: 'running', modelCount: 3 })
+const energySavingRate = ref(15.8)
+const totalEnergySaved = ref(1250.5)
+const pumpData = ref({
+  formationPressure: 25.6,
+  currentFrequency: 45.2,
+  optimizedFrequency: 42.1,
+  energyReduction: 23,
+  flowRate: 180.5,
+  power: 85.3
+})
+
+const modelConfigs = ref([
+  {
+    modelName: '娉ㄦ按娉甸鐜囦紭鍖栨ā鍨�',
+    version: 'v2.1.0',
+    status: 'active',
+    accuracy: '94.2%',
+    lastUpdate: '2024-01-15 14:30:00'
+  },
+  {
+    modelName: '鍦板眰鍘嬪姏棰勬祴妯″瀷',
+    version: 'v1.8.5',
+    status: 'active',
+    accuracy: '91.7%',
+    lastUpdate: '2024-01-14 09:15:00'
+  },
+  {
+    modelName: '鑳借�楀垎鏋愭ā鍨�',
+    version: 'v2.0.3',
+    status: 'standby',
+    accuracy: '89.3%',
+    lastUpdate: '2024-01-13 16:45:00'
+  }
+])
+
+const historyDialogVisible = ref(false)
+const optimizationHistory = ref([])
+
+// 鍥捐〃寮曠敤
+const frequencyChart = ref(null)
+const energyChart = ref(null)
+const savingChart = ref(null)
+
+// 鑷姩鍒锋柊鐩稿叧
+const autoRefreshStatus = ref(true)
+const autoRefreshTimer = ref(null)
+const chartInstances = ref([])
+
+// 璁$畻灞炴��
+const canControl = computed(() => {
+  return edgeServerStatus.value.status === 'online' && modelStatus.value.status === 'running'
+})
+
+const getProgressColor = computed(() => {
+  return (percentage) => {
+    if (percentage < 20) return '#909399'
+    if (percentage < 40) return '#E6A23C'
+    if (percentage < 60) return '#409EFF'
+    return '#67C23A'
+  }
+})
+
+// 鐢熸垚妯℃嫙鏁版嵁
+const generateMockData = () => {
+  // 鐢熸垚闅忔満鍦板眰鍘嬪姏 (20-30 MPa)
+  const formationPressure = 20 + Math.random() * 10
+  
+  // 鏍规嵁鍦板眰鍘嬪姏璁$畻浼樺寲棰戠巼
+  const baseFrequency = 40 + (formationPressure - 25) * 2
+  const currentFrequency = baseFrequency + (Math.random() - 0.5) * 4
+  const optimizedFrequency = Math.max(35, baseFrequency - Math.random() * 3)
+  
+  // 璁$畻鑳借�楅檷浣�
+  const energyReduction = Math.round((currentFrequency - optimizedFrequency) / currentFrequency * 100)
+  
+  // 璁$畻娴侀噺鍜屽姛鐜�
+  const flowRate = 150 + Math.random() * 60
+  const power = 70 + Math.random() * 30
+  
+  // 鏇存柊娉垫暟鎹�
+  pumpData.value = {
+    formationPressure: parseFloat(formationPressure.toFixed(1)),
+    currentFrequency: parseFloat(currentFrequency.toFixed(1)),
+    optimizedFrequency: parseFloat(optimizedFrequency.toFixed(1)),
+    energyReduction: Math.min(energyReduction, 35),
+    flowRate: parseFloat(flowRate.toFixed(1)),
+    power: parseFloat(power.toFixed(1))
+  }
+  
+  // 鏇存柊鑺傝兘鏁堟灉
+  energySavingRate.value = 12 + Math.random() * 8
+  totalEnergySaved.value += Math.random() * 2
+  
+  // 鏇存柊杈圭紭鏈嶅姟鍣ㄧ姸鎬�
+  edgeServerStatus.value.lastHeartbeat = Date.now()
+  
+  // 闅忔満鏇存柊妯″瀷鐘舵��
+  if (Math.random() > 0.95) {
+    modelStatus.value.modelCount = Math.max(1, modelStatus.value.modelCount + (Math.random() > 0.5 ? 1 : -1))
+  }
+  
+  // 娣诲姞浼樺寲鍘嗗彶璁板綍
+  if (Math.random() > 0.7) {
+    addOptimizationHistory()
+  }
+  
+  // 鏇存柊鍥捐〃鏁版嵁
+  updateCharts()
+}
+
+// 娣诲姞浼樺寲鍘嗗彶璁板綍
+const addOptimizationHistory = () => {
+  const timestamp = new Date().toLocaleString()
+  const record = {
+    timestamp,
+    formationPressure: pumpData.value.formationPressure,
+    oldFrequency: pumpData.value.currentFrequency,
+    newFrequency: pumpData.value.optimizedFrequency,
+    energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+    status: Math.random() > 0.1 ? 'success' : 'failed'
+  }
+  
+  optimizationHistory.value.unshift(record)
+  
+  // 淇濇寔鏈�澶�100鏉¤褰�
+  if (optimizationHistory.value.length > 100) {
+    optimizationHistory.value = optimizationHistory.value.slice(0, 100)
+  }
+}
+
+// 鏇存柊鍥捐〃鏁版嵁
+const updateCharts = () => {
+  chartInstances.value.forEach(instance => {
+    if (instance && instance.setOption) {
+      // 杩欓噷鍙互鏇存柊鍥捐〃鏁版嵁
+      // 涓轰簡绠�鍖栵紝鎴戜滑鍙槸閲嶆柊鍒濆鍖栧浘琛�
+    }
+  })
+}
+
+// 鏂规硶
+const refreshData = () => {
+  generateMockData()
+  ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
+}
+
+const applyOptimization = async () => {
+  try {
+    await ElMessageBox.confirm('纭畾瑕佸簲鐢ㄥ綋鍓嶇殑浼樺寲璁剧疆鍚楋紵', '纭鎿嶄綔', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    // 搴旂敤浼樺寲璁剧疆
+    pumpData.value.currentFrequency = pumpData.value.optimizedFrequency
+    ElMessage.success('浼樺寲璁剧疆搴旂敤鎴愬姛')
+    refreshData()
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('搴旂敤浼樺寲璁剧疆澶辫触')
+    }
+  }
+}
+
+const emergencyStop = async () => {
+  try {
+    await ElMessageBox.confirm('纭畾瑕佺揣鎬ュ仠姝㈡墍鏈夋敞姘存车鍚楋紵', '绱ф�ユ搷浣�', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'error'
+    })
+    
+    // 鎵ц绱ф�ュ仠姝㈤�昏緫
+    pumpData.value.currentFrequency = 0
+    pumpData.value.optimizedFrequency = 0
+    ElMessage.success('绱ф�ュ仠姝㈡墽琛屾垚鍔�')
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('绱ф�ュ仠姝㈡墽琛屽け璐�')
+    }
+  }
+}
+
+const showOptimizationHistory = () => {
+  historyDialogVisible.value = true
+}
+
+const updateModel = (model) => {
+  ElMessage.info(`鏇存柊妯″瀷: ${model.modelName}`)
+}
+
+const deleteModel = async (model) => {
+  try {
+    await ElMessageBox.confirm(`纭畾瑕佸垹闄ゆā鍨� ${model.modelName} 鍚楋紵`, '纭鍒犻櫎', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    const index = modelConfigs.value.findIndex(m => m.modelName === model.modelName)
+    if (index > -1) {
+      modelConfigs.value.splice(index, 1)
+      ElMessage.success('妯″瀷鍒犻櫎鎴愬姛')
+    }
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('妯″瀷鍒犻櫎澶辫触')
+    }
+  }
+}
+
+const toggleAutoRefresh = () => {
+  autoRefreshStatus.value = !autoRefreshStatus.value
+  if (autoRefreshStatus.value) {
+    startAutoRefresh()
+    ElMessage.success('鑷姩鍒锋柊宸插紑鍚�')
+  } else {
+    stopAutoRefresh()
+    ElMessage.info('鑷姩鍒锋柊宸插叧闂�')
+  }
+}
+
+const startAutoRefresh = () => {
+  stopAutoRefresh() // 鍏堝仠姝箣鍓嶇殑瀹氭椂鍣�
+  autoRefreshTimer.value = setInterval(() => {
+    generateMockData()
+  }, 60000) // 1鍒嗛挓 = 60000姣
+}
+
+const stopAutoRefresh = () => {
+  if (autoRefreshTimer.value) {
+    clearInterval(autoRefreshTimer.value)
+    autoRefreshTimer.value = null
+  }
+}
+
+const formatTime = (timestamp) => {
+  return new Date(timestamp).toLocaleTimeString()
+}
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+  // 棰戠巼浼樺寲瓒嬪娍鍥�
+  const frequencyChartInstance = echarts.init(frequencyChart.value)
+  const frequencyOption = {
+    title: { text: '娉甸鐜囦紭鍖栬秼鍔�' },
+    tooltip: { trigger: 'axis' },
+    legend: { data: ['褰撳墠棰戠巼', '浼樺寲棰戠巼', '鍦板眰鍘嬪姏'] },
+    xAxis: { type: 'category', data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'] },
+    yAxis: [
+      { type: 'value', name: '棰戠巼 (Hz)' },
+      { type: 'value', name: '鍘嬪姏 (MPa)' }
+    ],
+    series: [
+      {
+        name: '褰撳墠棰戠巼',
+        type: 'line',
+        data: [45.2, 44.8, 45.5, 45.1, 44.9, 45.2]
+      },
+      {
+        name: '浼樺寲棰戠巼',
+        type: 'line',
+        data: [42.1, 41.8, 42.3, 41.9, 41.7, 42.1]
+      },
+      {
+        name: '鍦板眰鍘嬪姏',
+        type: 'line',
+        yAxisIndex: 1,
+        data: [25.6, 25.8, 26.1, 25.9, 25.7, 25.6]
+      }
+    ]
+  }
+  frequencyChartInstance.setOption(frequencyOption)
+  chartInstances.value.push(frequencyChartInstance)
+
+  // 鑳借�楀垎鏋愬浘
+  const energyChartInstance = echarts.init(energyChart.value)
+  const energyOption = {
+    title: { text: '鏃ヨ兘鑰楀姣�' },
+    tooltip: { trigger: 'item' },
+    legend: { orient: 'vertical', left: 'left',top: 'center' },
+    series: [
+      {
+        name: '鑳借�楀垎甯�',
+        type: 'pie',
+        radius: '50%',
+        data: [
+          { value: 45, name: '娉ㄦ按娉�' },
+          { value: 25, name: '鐓ф槑绯荤粺' },
+          { value: 20, name: '閫氶绯荤粺' },
+          { value: 10, name: '鍏朵粬璁惧' }
+        ]
+      }
+    ]
+  }
+  energyChartInstance.setOption(energyOption)
+  chartInstances.value.push(energyChartInstance)
+
+  // 鑺傝兘鏁堟灉鍥�
+  const savingChartInstance = echarts.init(savingChart.value)
+  const savingOption = {
+    title: { text: '鑺傝兘鏁堟灉瓒嬪娍' },
+    tooltip: { trigger: 'axis' },
+    xAxis: { type: 'category', data: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'] },
+    yAxis: { type: 'value', name: '鑺傝兘鐜� (%)' },
+    series: [
+      {
+        name: '鑺傝兘鐜�',
+        type: 'bar',
+        data: [12.5, 15.2, 18.7, 16.3, 19.1, 17.8, 15.8]
+      }
+    ]
+  }
+  savingChartInstance.setOption(savingOption)
+  chartInstances.value.push(savingChartInstance)
+}
+
+// 鐢熸垚鍒濆鍘嗗彶鏁版嵁
+const generateInitialHistory = () => {
+  for (let i = 0; i < 20; i++) {
+    const timestamp = new Date(Date.now() - i * 3600000).toLocaleString()
+    const record = {
+      timestamp,
+      formationPressure: parseFloat((20 + Math.random() * 10).toFixed(1)),
+      oldFrequency: parseFloat((40 + Math.random() * 10).toFixed(1)),
+      newFrequency: parseFloat((35 + Math.random() * 8).toFixed(1)),
+      energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+      status: Math.random() > 0.1 ? 'success' : 'failed'
+    }
+    optimizationHistory.value.push(record)
+  }
+}
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  initCharts()
+  generateInitialHistory()
+  refreshData()
+  if (autoRefreshStatus.value) {
+    startAutoRefresh()
+  }
+})
+
+onUnmounted(() => {
+  stopAutoRefresh()
+  chartInstances.value.forEach(instance => {
+    if (instance && instance.dispose) {
+      instance.dispose()
+    }
+  })
+})
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+
+
+
+.status-section {
+  margin-bottom: 20px;
+}
+
+.status-card {
+  height: 140px;
+}
+
+.status-item {
+  display: flex;
+  align-items: center;
+  height: 100%;
+}
+
+.status-icon {
+  font-size: 48px;
+  margin-right: 20px;
+  color: #409EFF;
+}
+
+.status-info {
+  flex: 1;
+}
+
+.status-title {
+  font-size: 14px;
+  color: #909399;
+  margin-bottom: 8px;
+}
+
+.status-value {
+  font-size: 24px;
+  font-weight: bold;
+  margin-bottom: 8px;
+}
+
+.status-detail {
+  font-size: 12px;
+  color: #909399;
+}
+
+.status-value.online,
+.status-value.running {
+  color: #67C23A;
+}
+
+.status-value.offline,
+.status-value.stopped {
+  color: #F56C6C;
+}
+
+.status-value.success {
+  color: #67C23A;
+}
+
+.control-section,
+.model-section,
+.analysis-section {
+  margin-bottom: 20px;
+}
+
+.pump-control h4,
+.pump-chart h4 {
+  margin-bottom: 20px;
+  color: #303133;
+}
+
+.control-buttons {
+  margin-top: 20px;
+  text-align: center;
+}
+
+.control-buttons .el-button {
+  margin: 0 10px;
+}
+</style>

--
Gitblit v1.9.3