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