|
@@ -6,14 +6,24 @@
|
|
|
<el-input v-model="areaName" placeholder="请输入服务区名称" clearable size="small"
|
|
|
prefix-icon="el-icon-search"
|
|
|
style="margin-bottom: 20px"
|
|
|
+ @input="filterTree"
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="head-container">
|
|
|
<el-tree :data="areaOptions" :props="defaultProps" :expand-on-click-node="false"
|
|
|
:filter-node-method="filterNode" ref="tree"
|
|
|
- node-key="id" default-expand-all highlight-current @node-click="handleNodeClick"
|
|
|
- />
|
|
|
-
|
|
|
+ node-key="id" default-expand-all highlight-current @node-click="handleNodeClick">
|
|
|
+ <!-- 自定义节点内容:字符标识+名称 -->
|
|
|
+ <template #default="{ data }">
|
|
|
+ <div class="tree-node">
|
|
|
+ <!-- 区域节点添加 ▶ 符号 -->
|
|
|
+ <span v-if="data.type === 'area'" class="node-symbol area-symbol">▶</span>
|
|
|
+ <!-- 设备节点添加 ◬ 符号 -->
|
|
|
+ <span v-if="data.type === 'device'" class="node-symbol device-symbol">◬</span>
|
|
|
+ <span class="node-label">{{ data.label }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-tree>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
<el-col :span="20" :xs="24">
|
|
@@ -29,8 +39,8 @@
|
|
|
<el-date-picker
|
|
|
v-model="daterangeRecordTime"
|
|
|
style="width: 240px"
|
|
|
- value-format="yyyy-MM-dd HH:mm"
|
|
|
- type="datetimerange"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ type="daterange"
|
|
|
range-separator="-"
|
|
|
start-placeholder="开始日期"
|
|
|
end-placeholder="结束日期"
|
|
@@ -44,13 +54,12 @@
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
|
|
|
- <!-- 统计数据表格 -->
|
|
|
+ <!-- 用电统计数据表格 -->
|
|
|
<el-card class="box-card" v-if="activeTab==='first' && numElecMeterHData">
|
|
|
<div slot="header" class="clearfix">
|
|
|
<span>用电统计</span>
|
|
|
</div>
|
|
|
|
|
|
-
|
|
|
<el-table :data="[numElecMeterHData]" border style="width: 100%">
|
|
|
<!-- 第一行:用电量 -->
|
|
|
<el-table-column label="" align="center">
|
|
@@ -58,9 +67,9 @@
|
|
|
<span>{{ '电量(千瓦时)' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="合计" align="center">
|
|
|
+ <el-table-column label="合计" align="center" class-name="total-column">
|
|
|
<template slot-scope="scope">
|
|
|
- <span>{{ scope.row.total.quantity ? scope.row.total.quantity.toFixed(2) : '0.00' }}</span>
|
|
|
+ <span class="total-value">{{ scope.row.total.quantity ? scope.row.total.quantity.toFixed(2) : '0.00' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="平段" align="center">
|
|
@@ -91,9 +100,9 @@
|
|
|
<span>{{ '金额(元)' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="合计" align="center">
|
|
|
+ <el-table-column label="合计" align="center" class-name="total-column">
|
|
|
<template slot-scope="scope">
|
|
|
- <span>{{ scope.row.total.useCost ? scope.row.total.useCost.toFixed(2) : '0.00' }}</span>
|
|
|
+ <span class="total-value">{{ scope.row.total.useCost ? scope.row.total.useCost.toFixed(2) : '0.00' }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="平峰-金额(元)" align="center">
|
|
@@ -119,6 +128,40 @@
|
|
|
</el-table>
|
|
|
</el-card>
|
|
|
|
|
|
+ <!-- 用水统计数据表格 -->
|
|
|
+ <el-card class="box-card" v-if="activeTab==='second' && numWaterMeterHData">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <span>用水统计</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table :data="[numWaterMeterHData]" border style="width: 100%">
|
|
|
+ <!-- 第一行:用水量 -->
|
|
|
+ <el-table-column label="" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ '水量(吨)' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="合计" align="center" class-name="total-column">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span class="total-value">{{ scope.row.quantity ? scope.row.quantity.toFixed(2) : '0.00' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <!-- 第二行:总金额 -->
|
|
|
+ <el-table :data="[numWaterMeterHData]" border style="width: 100%; margin-top: 10px" :show-header="false">
|
|
|
+ <el-table-column label="" align="center" >
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ '金额(元)' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="合计" align="center" class-name="total-column">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span class="total-value">{{ scope.row.useCost ? scope.row.useCost.toFixed(2) : '0.00' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
<el-table v-if="activeTab === 'first'" v-loading="loading" :data="elecMeterHList">
|
|
|
<el-table-column label="表计名称" align="left" prop="deviceName" width="250px"/>
|
|
|
<el-table-column label="表计编号" align="left" prop="deviceCode"/>
|
|
@@ -145,7 +188,6 @@
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
-
|
|
|
<el-table v-if="activeTab === 'second'" v-loading="loading" :data="waterMeterHList">
|
|
|
<el-table-column type="selection" width="55" align="center"/>
|
|
|
<el-table-column label="表计名称" align="left" prop="deviceName" width="250"/>
|
|
@@ -222,14 +264,8 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import {
|
|
|
- listElecMeterH,
|
|
|
- delElecMeterH,
|
|
|
- addElecMeterH,
|
|
|
- updateElecMeterH,
|
|
|
- listWaterMeterH,
|
|
|
- getNumElecMeterH
|
|
|
-} from '@/api/device/elecMeterH'
|
|
|
+import { listElecMeterH, delElecMeterH, addElecMeterH, updateElecMeterH, getNumElecMeterH } from '@/api/device/elecMeterH'
|
|
|
+import { listWaterMeterH, getNumWaterMeterH } from '@/api/device/waterMeterH'
|
|
|
import { getDeviceTree } from '@/api/device/meterDevice'
|
|
|
|
|
|
export default {
|
|
@@ -238,6 +274,8 @@ export default {
|
|
|
return {
|
|
|
// 存储用电统计数据
|
|
|
numElecMeterHData: null,
|
|
|
+ // 存储用水统计数据
|
|
|
+ numWaterMeterHData: null,
|
|
|
activeTab: 'first',
|
|
|
// 遮罩层
|
|
|
loading: true,
|
|
@@ -308,8 +346,11 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
+ // 初始化默认查询时间范围
|
|
|
+ this.initDefaultDateRange();
|
|
|
+
|
|
|
this.getAreaTreeSelect().then(() => {
|
|
|
- /** 获取第一个有效的树节点*/
|
|
|
+ /** 获取第一个有效的设备节点 */
|
|
|
const firstValidNode = this.findFirstValidNode(this.areaOptions);
|
|
|
if (firstValidNode) {
|
|
|
this.queryParams.deviceCode = firstValidNode.id;
|
|
@@ -320,39 +361,78 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
methods: {
|
|
|
+ // 初始化默认查询时间范围:当月1号到今天
|
|
|
+ initDefaultDateRange() {
|
|
|
+ const today = new Date();
|
|
|
+ const currentYear = today.getFullYear();
|
|
|
+ const currentMonth = today.getMonth();
|
|
|
+
|
|
|
+ // 当月1号
|
|
|
+ const startDate = new Date(currentYear, currentMonth, 1);
|
|
|
+
|
|
|
+ // 当天
|
|
|
+ const endDate = new Date(today);
|
|
|
+
|
|
|
+ // 格式化为日期字符串 yyyy-MM-dd
|
|
|
+ const formatDate = (date) => {
|
|
|
+ const year = date.getFullYear();
|
|
|
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
+ const day = date.getDate().toString().padStart(2, '0');
|
|
|
+ return `${year}-${month}-${day}`;
|
|
|
+ };
|
|
|
+
|
|
|
+ this.daterangeRecordTime = [formatDate(startDate), formatDate(endDate)];
|
|
|
+ },
|
|
|
+
|
|
|
handleTabChange() {
|
|
|
if (this.activeTab === 'first') {
|
|
|
// 电表读数
|
|
|
- this.queryParams.meterCls = '45'
|
|
|
- this.getElecList()
|
|
|
+ this.queryParams.meterCls = '45';
|
|
|
} else if (this.activeTab === 'second') {
|
|
|
// 水表读数
|
|
|
- this.queryParams.meterCls = '70'
|
|
|
- this.getWaterList()
|
|
|
-
|
|
|
+ this.queryParams.meterCls = '70';
|
|
|
}
|
|
|
- this.getAreaTreeSelect()
|
|
|
- this.handleQuery()
|
|
|
+
|
|
|
+ // 重新加载树结构并重置设备选择
|
|
|
+ this.getAreaTreeSelect().then(() => {
|
|
|
+ // 切换tab后重新选择第一个设备节点
|
|
|
+ const firstValidNode = this.findFirstValidNode(this.areaOptions);
|
|
|
+ if (firstValidNode) {
|
|
|
+ this.queryParams.deviceCode = firstValidNode.id;
|
|
|
+ this.handleQuery();
|
|
|
+ } else {
|
|
|
+ // 如果没有找到设备节点,则清空数据
|
|
|
+ if (this.activeTab === 'first') {
|
|
|
+ this.getElecList();
|
|
|
+ } else {
|
|
|
+ this.getWaterList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
},
|
|
|
+
|
|
|
// 筛选节点
|
|
|
filterNode(value, data) {
|
|
|
if (!value) return true
|
|
|
return data.label.indexOf(value) !== -1
|
|
|
},
|
|
|
+ // 过滤树节点
|
|
|
+ filterTree() {
|
|
|
+ this.$refs.tree.filter(this.areaName);
|
|
|
+ },
|
|
|
// 节点单击事件
|
|
|
handleNodeClick(data) {
|
|
|
- if (data.id === null) {
|
|
|
- this.$message.warning('该节点不是设备不可点击');
|
|
|
- return;
|
|
|
+ // 仅处理设备节点
|
|
|
+ if (data.type === 'device') {
|
|
|
+ this.queryParams.deviceCode = data.id;
|
|
|
+ this.handleQuery();
|
|
|
}
|
|
|
- this.queryParams.deviceCode = data.id
|
|
|
- this.handleQuery()
|
|
|
-
|
|
|
+ // 区域节点不做处理
|
|
|
},
|
|
|
- /**第一个 id 非 null 的节点*/
|
|
|
+ /** 查找第一个设备节点 */
|
|
|
findFirstValidNode(nodes) {
|
|
|
for (const node of nodes) {
|
|
|
- if (node.id !== null) {
|
|
|
+ if (node.type === 'device') {
|
|
|
return node;
|
|
|
}
|
|
|
if (node.children && node.children.length > 0) {
|
|
@@ -362,12 +442,36 @@ export default {
|
|
|
}
|
|
|
return null;
|
|
|
},
|
|
|
- /**树结构*/
|
|
|
+ /** 树结构加载 */
|
|
|
async getAreaTreeSelect() {
|
|
|
await getDeviceTree(0, this.queryParams.meterCls, 0).then(response => {
|
|
|
- this.areaOptions = response.data
|
|
|
+ this.areaOptions = response.data;
|
|
|
+ // 为树节点添加类型标识以便样式控制
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.addTypeToNodeAttrs();
|
|
|
+ });
|
|
|
})
|
|
|
},
|
|
|
+ /** 为树节点DOM添加type属性用于样式控制 */
|
|
|
+ addTypeToNodeAttrs() {
|
|
|
+ if (!this.$refs.tree) return;
|
|
|
+
|
|
|
+ const addAttr = (nodes) => {
|
|
|
+ nodes.forEach(node => {
|
|
|
+ if (node.data && node.data.type) {
|
|
|
+ const el = this.$refs.tree.$el.querySelector(`[data-node-key="${node.key}"] .el-tree-node__content`);
|
|
|
+ if (el) {
|
|
|
+ el.setAttribute('data-type', node.data.type);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (node.children && node.children.length > 0) {
|
|
|
+ addAttr(node.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ addAttr(this.$refs.tree.store.root.children);
|
|
|
+ },
|
|
|
|
|
|
formatDateTime(dateTime) {
|
|
|
if (!dateTime) return ''
|
|
@@ -425,20 +529,29 @@ export default {
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
handleQuery() {
|
|
|
- this.queryParams.startRecTime = this.daterangeRecordTime[0]
|
|
|
- this.queryParams.endRecTime = this.daterangeRecordTime[1]
|
|
|
+ // 处理日期范围,自动拼接时分秒
|
|
|
+ if (this.daterangeRecordTime && this.daterangeRecordTime.length === 2) {
|
|
|
+ this.queryParams.startRecTime = this.daterangeRecordTime[0] + ' 00:00:00';
|
|
|
+ this.queryParams.endRecTime = this.daterangeRecordTime[1] + ' 23:59:59';
|
|
|
+ } else {
|
|
|
+ this.queryParams.startRecTime = null;
|
|
|
+ this.queryParams.endRecTime = null;
|
|
|
+ }
|
|
|
+
|
|
|
if (this.activeTab === 'first') {
|
|
|
this.queryParams.meterCls = '45'
|
|
|
- // this.queryParams.pageNum = 1
|
|
|
this.getElecList()
|
|
|
+ // 获取用电统计数据
|
|
|
+ this.getNumElecMeterH();
|
|
|
} else if (this.activeTab === 'second') {
|
|
|
this.queryParams.meterCls = '70'
|
|
|
- // this.queryParams.pageNum = 1
|
|
|
this.getWaterList()
|
|
|
+ // 获取用水统计数据
|
|
|
+ this.getNumWaterMeterH();
|
|
|
}
|
|
|
- // 获取统计数据
|
|
|
- this.getNumElecMeterH();
|
|
|
},
|
|
|
+
|
|
|
+ // 获取用电统计数据
|
|
|
async getNumElecMeterH() {
|
|
|
const query = {
|
|
|
deviceCode: this.queryParams.deviceCode,
|
|
@@ -449,13 +562,31 @@ export default {
|
|
|
const response = await getNumElecMeterH(query);
|
|
|
this.numElecMeterHData = response.data;
|
|
|
} catch (error) {
|
|
|
- this.$message.error("获取统计数据失败");
|
|
|
+ this.$message.error("获取用电统计数据失败");
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取用水统计数据
|
|
|
+ async getNumWaterMeterH() {
|
|
|
+ const query = {
|
|
|
+ deviceCode: this.queryParams.deviceCode,
|
|
|
+ startRecTime: this.queryParams.startRecTime,
|
|
|
+ endRecTime: this.queryParams.endRecTime,
|
|
|
+ };
|
|
|
+ try {
|
|
|
+ const response = await getNumWaterMeterH(query);
|
|
|
+ this.numWaterMeterHData = response.data;
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error("获取用水统计数据失败");
|
|
|
}
|
|
|
},
|
|
|
+
|
|
|
/** 重置按钮操作 */
|
|
|
resetQuery() {
|
|
|
this.daterangeRecordTime = []
|
|
|
this.resetForm('queryForm')
|
|
|
+ // 重置时重新初始化默认时间范围
|
|
|
+ this.initDefaultDateRange();
|
|
|
this.handleQuery()
|
|
|
},
|
|
|
/** 新增按钮操作 */
|
|
@@ -502,3 +633,116 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+/* 树节点样式 */
|
|
|
+.tree-node {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px; /* 符号与文字之间的间距 */
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+/* 字符标识样式 */
|
|
|
+.node-symbol {
|
|
|
+ display: inline-block;
|
|
|
+ width: 16px; /* 固定宽度确保对齐 */
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+/* 区域节点符号样式 */
|
|
|
+.area-symbol {
|
|
|
+ color: #666; /* 深灰色 */
|
|
|
+}
|
|
|
+
|
|
|
+/* 设备节点符号样式 */
|
|
|
+.device-symbol {
|
|
|
+ color: #337ab7; /* 蓝色 */
|
|
|
+}
|
|
|
+
|
|
|
+.node-label {
|
|
|
+ vertical-align: middle;
|
|
|
+}
|
|
|
+
|
|
|
+/* 鼠标样式控制 */
|
|
|
+.el-tree-node__content[data-type="area"] {
|
|
|
+ cursor: not-allowed;
|
|
|
+ opacity: 0.9;
|
|
|
+}
|
|
|
+
|
|
|
+.el-tree-node__content[data-type="device"] {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+/* 优化树节点hover效果 */
|
|
|
+.el-tree-node__content:hover {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+}
|
|
|
+
|
|
|
+.el-tree-node__content[data-type="area"]:hover {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+}
|
|
|
+
|
|
|
+/* 强调合计列的样式 - 若依框架适配 */
|
|
|
+/deep/ .total-column {
|
|
|
+ background-color: #f0f9ff !important;
|
|
|
+}
|
|
|
+
|
|
|
+/deep/ .total-column .cell {
|
|
|
+ position: relative;
|
|
|
+ padding-left: 12px !important;
|
|
|
+}
|
|
|
+
|
|
|
+/deep/ .total-column .cell::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ width: 4px;
|
|
|
+ height: 60%;
|
|
|
+ background-color: #409eff;
|
|
|
+ border-radius: 2px;
|
|
|
+}
|
|
|
+
|
|
|
+.total-value {
|
|
|
+ font-weight: bold !important;
|
|
|
+ font-size: 16px !important;
|
|
|
+ color: #2c3e50 !important;
|
|
|
+ display: inline-block;
|
|
|
+}
|
|
|
+
|
|
|
+.total-value::before {
|
|
|
+ content: '[';
|
|
|
+ margin-right: 2px;
|
|
|
+ color: #409eff !important;
|
|
|
+ font-weight: bold !important;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.total-value::after {
|
|
|
+ content: ']';
|
|
|
+ margin-left: 2px;
|
|
|
+ color: #409eff !important;
|
|
|
+ font-weight: bold !important;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 若依框架下的表格样式增强 */
|
|
|
+/deep/ .el-table .total-column {
|
|
|
+ background-color: #f0f9ff !important;
|
|
|
+}
|
|
|
+
|
|
|
+/deep/ .el-table .total-column td {
|
|
|
+ background-color: #f0f9ff !important;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保样式在若依主题下生效 */
|
|
|
+.app-container /deep/ .el-table .total-column {
|
|
|
+ background-color: #f0f9ff !important;
|
|
|
+}
|
|
|
+
|
|
|
+.app-container /deep/ .el-table .total-column .cell {
|
|
|
+ font-weight: bold !important;
|
|
|
+}
|