feat(ems): 添加产线选择和总表功能,增强表格配置选项

- 在电表管理页面添加产线选择下拉框和总表开关
- 在能耗表格页面添加配置选项:显示求和行、分表求和、误差计算
- 实现表格汇总行计算功能
- 添加误差和误差率计算功能
This commit is contained in:
2026-04-28 10:43:20 +08:00
parent 674859504f
commit 419fcb6c62
2 changed files with 131 additions and 14 deletions

View File

@@ -98,17 +98,6 @@
<span class="label">安装日期</span> <span class="label">安装日期</span>
<span class="value">{{ meter.installDate || '-' }}</span> <span class="value">{{ meter.installDate || '-' }}</span>
</div> </div>
<!-- <div class="info-item">
<span class="label">绑定库区</span>
<el-tag
v-if="getBindingWarehouse(meter.meterId)"
type="success"
size="small"
>
{{ getBindingWarehouse(meter.meterId) }}
</el-tag>
<el-tag v-else type="info" size="small">未绑定</el-tag>
</div> -->
<div class="info-item status-selector"> <div class="info-item status-selector">
<el-radio-group <el-radio-group
v-model="meter.status" v-model="meter.status"
@@ -153,6 +142,12 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="相关产线" prop="lineId">
<el-select v-model="meterForm.productionLine" placeholder="请选择相关产线" filterable clearable>
<el-option v-for="item in dict.type.sys_lines" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<!-- 基本信息 --> <!-- 基本信息 -->
<el-form-item label="型号" prop="model"> <el-form-item label="型号" prop="model">
<el-input v-model="meterForm.model" placeholder="请输入设备型号" /> <el-input v-model="meterForm.model" placeholder="请输入设备型号" />
@@ -164,6 +159,9 @@
<el-date-picker v-model="meterForm.installDate" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" /> <el-date-picker v-model="meterForm.installDate" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" />
</el-form-item> </el-form-item>
<el-form-item label="是总表" prop="isTotalMeter">
<el-switch v-model="meterForm.isTotalMeter" :active-value="1" :inactive-value="0" active-text="是" inactive-text="否" />
</el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="meterDialogVisible = false"> </el-button> <el-button @click="meterDialogVisible = false"> </el-button>
@@ -181,6 +179,7 @@ import { fetchEnergyLinkMatrix, addEnergyLink } from '@/api/ems/energyLink'
export default { export default {
name: "MeterManage", name: "MeterManage",
dicts: ['sys_lines'],
data() { data() {
return { return {
loading: false, loading: false,

View File

@@ -18,7 +18,7 @@
<div v-else> <div v-else>
<!-- 增加日期筛选默认选中当前月份用户可以切换月份 --> <!-- 增加日期筛选默认选中当前月份用户可以切换月份 -->
<div style="margin-bottom: 16px; display: flex; align-items: center;"> <div style="margin-bottom: 16px; display: flex; align-items: center; flex-wrap: wrap; gap: 10px;">
<el-date-picker <el-date-picker
v-model="selectedMonth" v-model="selectedMonth"
type="month" type="month"
@@ -29,10 +29,17 @@
style="width: 150px;" style="width: 150px;"
/> />
<el-button style="margin-left: 10px;" icon="el-icon-refresh" @click="handleRefresh">刷新</el-button> <el-button icon="el-icon-refresh" @click="handleRefresh">刷新</el-button>
</div> </div>
<el-table :data="tableData" style="width: 100%" border> <!-- 配置选项 -->
<div style="margin-bottom: 16px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
<el-checkbox v-model="configOptions.showSumRow">显示求和行</el-checkbox>
<el-checkbox v-model="configOptions.sumSubMeters" style="margin-left: 20px;">对分表求和排除总表</el-checkbox>
<el-checkbox v-model="configOptions.showError" style="margin-left: 20px;" :disabled="!canShowError">显示误差计算</el-checkbox>
</div>
<el-table :data="tableData" style="width: 100%" border :show-summary="configOptions.showSumRow" :summary-method="getSummaries">
<el-table-column prop="date" label="日期" width="120" /> <el-table-column prop="date" label="日期" width="120" />
<el-table-column v-for="meter in meters" :key="meter.meterId" :prop="`meter_${meter.meterId}`" <el-table-column v-for="meter in meters" :key="meter.meterId" :prop="`meter_${meter.meterId}`"
:label="meter.meterCode"> :label="meter.meterCode">
@@ -41,6 +48,24 @@
@change="(e) => handleCellChange(scope.row, meter.meterId, e)" /> @change="(e) => handleCellChange(scope.row, meter.meterId, e)" />
</template> </template>
</el-table-column> </el-table-column>
<!-- 分表求和列 -->
<el-table-column v-if="configOptions.sumSubMeters" label="分表合计" width="120">
<template slot-scope="scope">
{{ getSubMetersSum(scope.row).toFixed(2) }}
</template>
</el-table-column>
<!-- 误差列 -->
<el-table-column v-if="configOptions.showError && canShowError" label="误差" width="120">
<template slot-scope="scope">
{{ getRowError(scope.row).toFixed(2) }}
</template>
</el-table-column>
<!-- 误差率列 -->
<el-table-column v-if="configOptions.showError && canShowError" label="误差率" width="120">
<template slot-scope="scope">
{{ getRowErrorPercent(scope.row).toFixed(2) }}%
</template>
</el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
@@ -72,8 +97,21 @@ export default {
rightLoading: false, rightLoading: false,
selectedMonth: currentMonth, selectedMonth: currentMonth,
originalData: [], // 用于存储原始数据 originalData: [], // 用于存储原始数据
configOptions: {
showSumRow: false,
sumSubMeters: false,
showError: false
},
sumRowData: {} // 存储求和行数据
}; };
}, },
computed: {
// 判断是否可以显示误差计算(需要有且仅有一个总表)
canShowError() {
const totalMeters = this.meters.filter(m => m.isTotalMeter === 1);
return totalMeters.length === 1;
}
},
mounted() { mounted() {
this.loadEnergyTypes(); this.loadEnergyTypes();
}, },
@@ -277,6 +315,86 @@ export default {
handleAddMeter() { handleAddMeter() {
this.$router.push({ path: '/ems/meter/manage' }); this.$router.push({ path: '/ems/meter/manage' });
}, },
// 计算一行中所有分表的和
getSubMetersSum(row) {
const subMeters = this.meters.filter(m => m.isTotalMeter !== 1);
return subMeters.reduce((sum, meter) => {
const value = Number(row[`meter_${meter.meterId}`]) || 0;
return sum + value;
}, 0);
},
// 计算一行的误差(总表 - 分表合计)
getRowError(row) {
if (!this.canShowError) return 0;
const totalMeter = this.meters.find(m => m.isTotalMeter === 1);
const totalValue = Number(row[`meter_${totalMeter.meterId}`]) || 0;
const subMetersSum = this.getSubMetersSum(row);
return totalValue - subMetersSum;
},
// 计算一行的误差百分比
getRowErrorPercent(row) {
if (!this.canShowError) return 0;
const totalMeter = this.meters.find(m => m.isTotalMeter === 1);
const totalValue = Number(row[`meter_${totalMeter.meterId}`]) || 0;
if (totalValue === 0) return 0;
const error = this.getRowError(row);
return (error / totalValue) * 100;
},
// 计算表格汇总行
getSummaries(param) {
const { columns, data } = param;
const sums = [];
// 如果不显示求和行,返回空数组
if (!this.configOptions.showSumRow) {
return sums;
}
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计';
return;
}
// 获取当前列对应的表计
const prop = column.property;
if (prop && prop.startsWith('meter_')) {
// 计算该列的和
const values = data.map(item => Number(item[prop]) || 0);
const sum = values.reduce((prev, curr) => prev + curr, 0);
sums[index] = sum.toFixed(2);
return;
}
// 分表合计列的汇总
if (column.label === '分表合计' && this.configOptions.sumSubMeters) {
const sum = data.reduce((total, row) => total + this.getSubMetersSum(row), 0);
sums[index] = sum.toFixed(2);
return;
}
// 误差列的汇总
if (column.label === '误差' && this.configOptions.showError && this.canShowError) {
const sum = data.reduce((total, row) => total + this.getRowError(row), 0);
sums[index] = sum.toFixed(2);
return;
}
// 误差率列不进行汇总
if (column.label === '误差率') {
sums[index] = '-';
return;
}
sums[index] = '';
});
return sums;
},
} }
}; };
</script> </script>