From cd6eb9089e893cf7fa998543af1125dbef81a355 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 15 八月 2025 14:29:28 +0800
Subject: [PATCH] 电表采集页面添加
---
src/views/energyManagement/meterCollection/index.vue | 556 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 556 insertions(+), 0 deletions(-)
diff --git a/src/views/energyManagement/meterCollection/index.vue b/src/views/energyManagement/meterCollection/index.vue
new file mode 100644
index 0000000..8b2636b
--- /dev/null
+++ b/src/views/energyManagement/meterCollection/index.vue
@@ -0,0 +1,556 @@
+<template>
+ <div class="app-container">
+ <el-card class="box-card">
+ <div slot="header" class="clearfix">
+ <span>鐢佃〃閲囬泦绠$悊</span>
+ <el-button style="float: right; padding: 3px 0" link @click="refreshData">
+ <i class="el-icon-refresh"></i> 鍒锋柊
+ </el-button>
+ </div>
+
+ <!-- 娴嬭瘯鎸夐挳 -->
+ <el-row :gutter="20" style="margin-bottom: 15px;">
+ <el-col :span="24">
+ <el-button @click="addTestData" type="primary" size="small">娣诲姞娴嬭瘯鏁版嵁</el-button>
+ <el-button @click="clearData" type="danger" size="small">娓呯┖鏁版嵁</el-button>
+ <el-button @click="testChart" type="success" size="small">娴嬭瘯鍥捐〃</el-button>
+ </el-col>
+ </el-row>
+
+ <!-- 鎼滅储鍖哄煙 -->
+ <el-row :gutter="20" class="search-row">
+ <el-col :span="6">
+ <el-input
+ v-model="searchForm.meterNo"
+ placeholder="璇疯緭鍏ョ數琛ㄧ紪鍙�"
+ clearable
+ @keyup.enter.native="handleSearch"
+ >
+ <i slot="prefix" class="el-input__icon el-icon-search"></i>
+ </el-input>
+ </el-col>
+ <el-col :span="6">
+ <el-select v-model="searchForm.location" placeholder="璇烽�夋嫨浣嶇疆" clearable>
+ <el-option label="鐢熶骇杞﹂棿A" value="杞﹂棿A"></el-option>
+ <el-option label="鐢熶骇杞﹂棿B" value="杞﹂棿B"></el-option>
+ <el-option label="鍔炲叕鍖哄煙" value="鍔炲叕鍖�"></el-option>
+ <el-option label="閰嶇數瀹�" value="閰嶇數瀹�"></el-option>
+ </el-select>
+ </el-col>
+ <el-col :span="6">
+ <el-date-picker
+ v-model="searchForm.dateRange"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ format="yyyy-MM-dd"
+ value-format="yyyy-MM-dd"
+ />
+ </el-col>
+ <el-col :span="6">
+ <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
+ <el-button @click="resetSearch">閲嶇疆</el-button>
+ </el-col>
+ </el-row>
+
+ <!-- 鐢佃〃鍒楄〃 -->
+ <el-table
+ :data="meterList"
+ style="width: 100%"
+ v-loading="loading"
+ border
+ stripe
+ height="calc(100vh - 22em)"
+ >
+ <el-table-column prop="meterNo" label="鐢佃〃缂栧彿" width="120" />
+ <el-table-column prop="location" label="瀹夎浣嶇疆" width="120" />
+ <el-table-column prop="meterType" label="鐢佃〃绫诲瀷" width="120" />
+ <el-table-column prop="voltage" label="鐢靛帇绛夌骇" width="100" />
+ <el-table-column prop="currentReading" label="褰撳墠璇绘暟(kWh)" width="140" />
+ <el-table-column prop="lastReading" label="涓婃璇绘暟(kWh)" width="140" />
+ <el-table-column prop="consumption" label="鐢ㄧ數閲�(kWh)" width="120" />
+ <el-table-column prop="power" label="鍔熺巼(kW)" width="100" />
+ <el-table-column prop="powerFactor" label="鍔熺巼鍥犳暟" width="100" />
+ <el-table-column prop="status" label="鐘舵��" width="80">
+ <template #default="scope">
+ <el-tag :type="scope.row.status === '姝e父' ? 'success' : 'danger'">
+ {{ scope.row.status }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="lastUpdateTime" label="鏈�鍚庢洿鏂版椂闂�" width="160" />
+ <el-table-column label="鎿嶄綔" width="180" fixed="right" align="center">
+ <template #default="scope">
+ <el-button link @click="viewDetails(scope.row)">
+ 鏌ョ湅璇︽儏
+ </el-button>
+ <el-button link @click="manualCollection(scope.row)">
+ 鎵嬪姩閲囬泦
+ </el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ <!-- 鍒嗛〉 -->
+ <pagination
+ :total="pagination.total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="pagination.currentPage"
+ :limit="pagination.pageSize"
+ @pagination="handleCurrentChange"
+ />
+ </el-card>
+
+ <!-- 璇︽儏瀵硅瘽妗� -->
+ <el-dialog
+ title="鐢佃〃璇︽儏"
+ v-model="detailDialogVisible"
+ width="60%"
+ @opened="onDialogOpened"
+ >
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鐢佃〃缂栧彿:</label>
+ <span>{{ currentMeter.meterNo }}</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>瀹夎浣嶇疆:</label>
+ <span>{{ currentMeter.location }}</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鐢佃〃绫诲瀷:</label>
+ <span>{{ currentMeter.meterType }}</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鐢靛帇绛夌骇:</label>
+ <span>{{ currentMeter.voltage }}</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>褰撳墠璇绘暟:</label>
+ <span>{{ currentMeter.currentReading }} kWh</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>涓婃璇绘暟:</label>
+ <span>{{ currentMeter.lastReading }} kWh</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鐢ㄧ數閲�:</label>
+ <span>{{ currentMeter.consumption }} kWh</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鍔熺巼:</label>
+ <span>{{ currentMeter.power }} kW</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鍔熺巼鍥犳暟:</label>
+ <span>{{ currentMeter.powerFactor }}</span>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鐘舵��:</label>
+ <el-tag :type="currentMeter.status === '姝e父' ? 'success' : 'danger'">
+ {{ currentMeter.status }}
+ </el-tag>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="detail-item">
+ <label>鏈�鍚庢洿鏂版椂闂�:</label>
+ <span>{{ currentMeter.lastUpdateTime }}</span>
+ </div>
+ </el-col>
+ </el-row>
+
+ <!-- 鐢ㄧ數瓒嬪娍鍥� -->
+ <div style="margin-top: 20px;">
+ <h4>24灏忔椂鐢ㄧ數瓒嬪娍</h4>
+ <div ref="chartContainer" style="height: 300px;"></div>
+ </div>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+ name: 'MeterCollection',
+ data() {
+ return {
+ loading: false,
+ searchForm: {
+ meterNo: '',
+ location: '',
+ dateRange: []
+ },
+ meterList: [],
+ pagination: {
+ currentPage: 1,
+ pageSize: 10,
+ total: 0
+ },
+ detailDialogVisible: false,
+ currentMeter: {},
+ chart: null
+ }
+ },
+ created() {
+ // 绔嬪嵆鐢熸垚涓�浜涙祴璇曟暟鎹�
+ this.meterList = [
+ {
+ id: 1,
+ meterNo: 'M001',
+ location: '杞﹂棿A',
+ meterType: '鏅鸿兘鐢佃〃',
+ voltage: '380V',
+ currentReading: 8500,
+ lastReading: 8400,
+ consumption: 100,
+ power: '75.5',
+ powerFactor: '0.85',
+ status: '姝e父',
+ lastUpdateTime: '2024-01-15 10:30:00'
+ },
+ {
+ id: 2,
+ meterNo: 'M002',
+ location: '杞﹂棿B',
+ meterType: '澶氬姛鑳界數琛�',
+ voltage: '220V',
+ currentReading: 6200,
+ lastReading: 6100,
+ consumption: 100,
+ power: '45.2',
+ powerFactor: '0.92',
+ status: '姝e父',
+ lastUpdateTime: '2024-01-15 10:25:00'
+ }
+ ]
+ this.pagination.total = this.meterList.length
+ },
+ mounted() {
+ // 寤惰繜涓�鐐规椂闂村啀璋冪敤锛岀‘淇滵OM宸茬粡娓叉煋
+ this.$nextTick(() => {
+ this.getMeterList()
+ })
+ },
+ watch: {
+ meterList: {
+ handler(newVal) {
+ console.log('meterList鏁版嵁鍙樺寲:', newVal)
+ },
+ deep: true,
+ immediate: true
+ }
+ },
+ methods: {
+ // 鑾峰彇鐢佃〃鍒楄〃
+ getMeterList() {
+ this.loading = true
+ // 妯℃嫙API璋冪敤
+ setTimeout(() => {
+ const mockData = this.generateMockData()
+ this.meterList = mockData
+ this.pagination.total = this.meterList.length
+ this.loading = false
+ }, 500)
+ },
+
+ // 鐢熸垚妯℃嫙鏁版嵁
+ generateMockData() {
+ const locations = ['杞﹂棿A', '杞﹂棿B', '鍔炲叕鍖�', '閰嶇數瀹�']
+ const meterTypes = ['鏅鸿兘鐢佃〃', '澶氬姛鑳界數琛�', '鏅�氱數琛�']
+ const voltages = ['220V', '380V', '10kV']
+ const statuses = ['姝e父', '寮傚父']
+
+ const data = []
+ for (let i = 1; i <= 25; i++) {
+ const currentReading = Math.floor(Math.random() * 10000) + 5000
+ const lastReading = currentReading - Math.floor(Math.random() * 100) - 10
+ const consumption = currentReading - lastReading
+ const power = Math.random() * 100 + 20
+ const powerFactor = (Math.random() * 0.3 + 0.7).toFixed(2)
+
+ data.push({
+ id: i,
+ meterNo: `M${String(i).padStart(3, '0')}`,
+ location: locations[Math.floor(Math.random() * locations.length)],
+ meterType: meterTypes[Math.floor(Math.random() * meterTypes.length)],
+ voltage: voltages[Math.floor(Math.random() * voltages.length)],
+ currentReading: currentReading,
+ lastReading: lastReading,
+ consumption: consumption,
+ power: power.toFixed(2),
+ powerFactor: powerFactor,
+ status: statuses[Math.floor(Math.random() * statuses.length)],
+ lastUpdateTime: this.formatDate(new Date(Date.now() - Math.random() * 86400000))
+ })
+ }
+ return data
+ },
+
+ // 鏍煎紡鍖栨棩鏈�
+ formatDate(date) {
+ const year = date.getFullYear()
+ const month = String(date.getMonth() + 1).padStart(2, '0')
+ const day = String(date.getDate()).padStart(2, '0')
+ const hours = String(date.getHours()).padStart(2, '0')
+ const minutes = String(date.getMinutes()).padStart(2, '0')
+ return `${year}-${month}-${day} ${hours}:${minutes}`
+ },
+
+ // 鎼滅储
+ handleSearch() {
+ this.pagination.currentPage = 1
+ this.getMeterList()
+ },
+
+ // 閲嶇疆鎼滅储
+ resetSearch() {
+ this.searchForm = {
+ meterNo: '',
+ location: '',
+ dateRange: []
+ }
+ this.handleSearch()
+ },
+
+ // 鏌ョ湅璇︽儏
+ viewDetails(row) {
+ this.currentMeter = row
+ this.detailDialogVisible = true
+ },
+
+ // 瀵硅瘽妗嗘墦寮�鍚庡垵濮嬪寲鍥捐〃
+ onDialogOpened() {
+ this.$nextTick(() => {
+ setTimeout(() => {
+ this.initChart()
+ }, 100)
+ })
+ },
+
+ // 鎵嬪姩閲囬泦
+ manualCollection(row) {
+ this.$message.success(`姝e湪閲囬泦鐢佃〃 ${row.meterNo} 鐨勬暟鎹�...`)
+ // 妯℃嫙閲囬泦杩囩▼
+ setTimeout(() => {
+ row.currentReading = Math.floor(Math.random() * 100) + row.currentReading
+ row.lastUpdateTime = this.formatDate(new Date())
+ this.$message.success('鏁版嵁閲囬泦瀹屾垚')
+ }, 1000)
+ },
+
+ // 鍒锋柊鏁版嵁
+ refreshData() {
+ this.getMeterList()
+ this.$message.success('鏁版嵁宸插埛鏂�')
+ },
+
+ // 娣诲姞娴嬭瘯鏁版嵁
+ addTestData() {
+ const testData = {
+ id: Date.now(),
+ meterNo: `M${String(this.meterList.length + 1).padStart(3, '0')}`,
+ location: '娴嬭瘯浣嶇疆',
+ meterType: '娴嬭瘯鐢佃〃',
+ voltage: '220V',
+ currentReading: Math.floor(Math.random() * 10000) + 1000,
+ lastReading: Math.floor(Math.random() * 5000) + 500,
+ consumption: Math.floor(Math.random() * 100) + 10,
+ power: (Math.random() * 100 + 10).toFixed(2),
+ powerFactor: (Math.random() * 0.3 + 0.7).toFixed(2),
+ status: '姝e父',
+ lastUpdateTime: this.formatDate(new Date())
+ }
+ this.meterList.push(testData)
+ this.pagination.total = this.meterList.length
+ this.$message.success('娴嬭瘯鏁版嵁宸叉坊鍔�')
+ },
+
+ // 娓呯┖鏁版嵁
+ clearData() {
+ this.meterList = []
+ this.pagination.total = 0
+ this.$message.success('鏁版嵁宸叉竻绌�')
+ },
+
+ // 娴嬭瘯鍥捐〃
+ testChart() {
+ this.$message.info('鍥捐〃娴嬭瘯鍔熻兘')
+ // 鍒涘缓涓�涓祴璇曞璇濇鏉ユ祴璇曞浘琛�
+ this.currentMeter = {
+ meterNo: 'TEST001',
+ location: '娴嬭瘯浣嶇疆',
+ meterType: '娴嬭瘯鐢佃〃',
+ voltage: '220V',
+ currentReading: 1000,
+ lastReading: 900,
+ consumption: 100,
+ power: '50.0',
+ powerFactor: '0.85',
+ status: '姝e父',
+ lastUpdateTime: '2024-01-15 12:00:00'
+ }
+ this.detailDialogVisible = true
+ },
+
+ // 鍒嗛〉澶у皬鏀瑰彉
+ handleSizeChange(val) {
+ this.pagination.pageSize = val
+ this.getMeterList()
+ },
+
+ // 褰撳墠椤垫敼鍙�
+ handleCurrentChange(val) {
+ this.pagination.pageSize = val.limit
+ this.pagination.currentPage = val.page
+ this.getMeterList()
+ },
+
+ // 鍒濆鍖栧浘琛�
+ initChart() {
+ try {
+ if (this.chart) {
+ this.chart.dispose()
+ this.chart = null
+ }
+
+ // 纭繚DOM鍏冪礌瀛樺湪
+ if (!this.$refs.chartContainer) {
+ console.error('鍥捐〃瀹瑰櫒涓嶅瓨鍦紝绛夊緟DOM鏇存柊...')
+ // 濡傛灉瀹瑰櫒涓嶅瓨鍦紝绛夊緟涓�涓嬪啀璇�
+ setTimeout(() => {
+ this.initChart()
+ }, 100)
+ return
+ }
+
+ // 妫�鏌ュ鍣ㄥ昂瀵�
+ const container = this.$refs.chartContainer
+ if (container.offsetWidth === 0 || container.offsetHeight === 0) {
+ setTimeout(() => {
+ this.initChart()
+ }, 100)
+ return
+ }
+ this.chart = echarts.init(container)
+
+ // 鐢熸垚24灏忔椂妯℃嫙鏁版嵁
+ const hours = []
+ const consumption = []
+ for (let i = 0; i < 24; i++) {
+ hours.push(`${i}:00`)
+ consumption.push(Math.floor(Math.random() * 50) + 20)
+ }
+
+ const option = {
+ title: {
+ text: '24灏忔椂鐢ㄧ數閲忚秼鍔�',
+ left: 'center'
+ },
+ tooltip: {
+ trigger: 'axis',
+ formatter: '{b}<br/>鐢ㄧ數閲�: {c} kWh'
+ },
+ xAxis: {
+ type: 'category',
+ data: hours,
+ axisLabel: {
+ rotate: 45
+ }
+ },
+ yAxis: {
+ type: 'value',
+ name: '鐢ㄧ數閲� (kWh)'
+ },
+ series: [{
+ data: consumption,
+ type: 'line',
+ smooth: true,
+ areaStyle: {
+ opacity: 0.3
+ },
+ itemStyle: {
+ color: '#409EFF'
+ }
+ }]
+ }
+
+ this.chart.setOption(option)
+ } catch (error) {
+ console.error('鍥捐〃鍒濆鍖栧け璐�:', error)
+ this.$message.error('鍥捐〃鍒濆鍖栧け璐�: ' + error.message)
+ }
+ }
+ },
+
+ beforeUnmount() {
+ if (this.chart) {
+ try {
+ this.chart.dispose()
+ this.chart = null
+ } catch (error) {
+ console.error('娓呯悊鍥捐〃澶辫触:', error)
+ }
+ }
+ }
+}
+</script>
+
+<style scoped>
+.search-row {
+ margin-bottom: 20px;
+}
+
+.pagination {
+ margin-top: 20px;
+ text-align: right;
+}
+
+.el-table {
+ margin-top: 20px;
+}
+
+.detail-item {
+ margin-bottom: 15px;
+ padding: 10px;
+ border: 1px solid #ebeef5;
+ border-radius: 4px;
+ background-color: #fafafa;
+}
+
+.detail-item label {
+ font-weight: bold;
+ color: #606266;
+ margin-right: 10px;
+ min-width: 100px;
+ display: inline-block;
+}
+
+.detail-item span {
+ color: #303133;
+}
+
+.detail-item .el-tag {
+ margin-left: 0;
+}
+</style>
--
Gitblit v1.9.3