factory_web/src/views/enm_energy/electric_peak.vue

463 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container" id="app-container" style="height: 100%">
<el-header id="app-header">
<div class="left-panel">
<el-select
v-model="query.type"
placeholder="查询类型"
clearable
class="headerSearch"
>
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
<el-select
v-model="query.mgroupName"
placeholder="查询工段"
clearable
class="headerSearch"
>
<el-option
v-for="item in mgroups"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
<el-date-picker
v-model="query.day"
type="date"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
placeholder="天"
v-if="query.type==0"
style="margin-right: 6px"
/>
<el-date-picker
v-model="query.month"
type="month"
value-format="YYYY-MM"
format="YYYY-MM"
placeholder="查询月份"
v-if="query.type==1"
class="headerSearch"
/>
<el-date-picker
v-model="query.year"
type="year"
value-format="YYYY"
format="YYYY"
placeholder="查询年份"
v-if="query.type==2"
class="headerSearch"
/>
<el-date-picker
v-model="daterange"
type="datetimerange"
:shortcuts="shortcuts"
range-separator="To"
start-placeholder="Start date"
end-placeholder="End date"
placeholder="时间范围"
value-format="YYYY-MM-DD hh:mm:ss"
v-if="query.type==3"
style="margin-right: 6px"
@change="changeDate"
/>
<el-button
type="primary"
icon="el-icon-search"
@click="dateChange"
></el-button>
<el-button
type="primary"
@click="exportExcel()"
:loading="exportLoading"
>导出xlsx
</el-button>
<el-button
type="primary"
@click="showBarChart()"
icon="el-icon-pie-chart"
>趋势图
</el-button>
<!-- <el-button type="primary" @click="handlePrint">打印 </el-button> -->
</div>
</el-header>
<el-card style="margin-top:5px">
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<el-table
id = "greenHeadTable"
:data="tableData"
style="width: 70%"
border
:height="tableHeight"
>
<el-table-column label="100KW以上设备用电峰谷平" align="center" width="100" fixed>
<el-table-column label="设备" prop="mpoint__name" min-width="110" fixed></el-table-column>
<el-table-column label="单位" prop="unit" min-width="110" fixed></el-table-column>
<!-- 动态渲染尖峰、波峰、平谷、波谷、深谷 -->
<el-table-column
v-for="column in columns"
:key="column.prop"
:label="column.label"
:prop="column.prop"
min-width="120"
></el-table-column>
</el-table-column>
</el-table>
<el-table
:data="tableDatas2"
border
style="margin-left: 10px; margin-top: 10px; width: 500px; table-layout: fixed;"
:key="timeStamp"
class="myTable"
>
<!-- 第一列 -->
<el-table-column
label="峰谷平时间段划分"
prop="type"
width="150"
align="center"
>
</el-table-column>
<!-- 第二列 -->
<el-table-column
label="时间段"
prop="time"
align="left"
>
</el-table-column>
</el-table>
</div>
</el-card>
</div>
<el-dialog
title="柱状图"
v-model="isChartDialogVisible"
width="80%"
@close="onDialogClose">
<div
id="barChart"
style="width: 100%; height: 400px;"
></div>
<template #footer>
<el-button @click="isChartDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</template>
<script>
import * as echarts from 'echarts';
export default {
data() {
return {
query:{
type:0,
day:'',
mgroupName:'',
year:'',
month:'',
yearStart:'',
start_time:'',
end_time:'',
},
tableHeight:800,
columns: [
{ label: '尖峰', prop: 'peak' },
{ label: '波峰', prop: 'high' },
{ label: '平谷', prop: 'flat' },
{ label: '波谷', prop: 'low' },
{ label: '深谷', prop: 'deep' },
],
tableData:[],
tableDatas2: [
{ type: "波峰", time: "8:00--11:00 19:00-24:00" },
{ type: "尖峰", time: "7月 21:00--23:00, 1、11、12月19:00--21:00" },
{ type: "平谷", time: "11:00--13:00 17:00-19:00 00:00-4:00" },
{ type: "波谷", time: "4:00--8:00 13:00-17:00" },
{ type: "深谷", time: "5、6、7、8月 14:00--16:00" },
],
tableDatas_day: [],
tableDatas_range:[],
mpoint_name: [],
isChartDialogVisible: false, // 控制弹窗显示状态
mpointList: [],
daterange:[],
barChartData: {},
options:[
{id:0,name:'日统计'},
{id:1,name:'月统计'},
{id:2,name:'年统计'},
{id:3,name:'时间范围'},
],
mgroups: [
{id:0,name:'电石渣'},
{id:1,name:'原料磨'},
{id:2,name:'生料工序(二次配料)'},
{id:3,name:'回转窑'},
{id:4,name:'煤磨'},
{id:5,name:'水泥磨'},
{id:6,name:'水泥包装'},
],
col_list : ['peak','high','low','deep','flat'],
row_translate: ['尖峰', '波峰', '波谷', '深谷', '平谷'],
colors :["#EB1B1D", "#FE9900", "#0E4E51", "#2B8C05", "#A9C0A0"],// 自定义颜色
};
},
mounted() {
var myDate = new Date();
let month = myDate.getMonth()+1;
if(month<10){
month = '0'+month;
}
this.query.month = myDate.getFullYear()+'-'+month;
this.query.day = myDate.getFullYear()+'-'+(myDate.getMonth()+1)+'-'+myDate.getDate();
this.query.year = myDate.getFullYear();
this.dateChange();
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
let that = this;
if (columnIndex == 0) {
if (that.indexList.indexOf(rowIndex) > -1) {
let rowspans = that.mgroupObj[row.mgroupName];
return {
rowspan: rowspans,
colspan: 1,
};
} else {
return {
rowspan: 1,
colspan: 0,
};
}
}
},
changeDate(){
let obj = {};
obj.type = "hour";
obj.start_time = this.daterange[0];
obj.end_time = this.daterange[1];
obj.mpoint__in = this.mpointList[0];
obj.page = 0;
this.$API.enm.mpointstat.groupValues.req(obj).then((res) => {
//处理res数组中的 total_val 字段 保留两位
res.forEach(item => {
item.total_val = Number(item.total_val).toFixed(2);
});
this.tableDatas_range = res;
});
},
dateChange() {
let that = this;
that.mpointList = []; // 清空数组
let arr = [],
obj = {};
console.log(that.query.mgroupName, 'that.query.mgroupName')
that.$API.enm.mpoint.list
.req({
page: 0,
enabled: 1,
need_display: 1,
mgroup__name: that.query.mgroupName,
mpoint_ep_monitored__power_kw__gte: 100,
ordering: "report_sortstr",
material__code__in: "elec",
query: "{ id, name, nickname, mgroup_name, unit, report_sortstr, ep_monitored_name, }",
})
.then((res) => {
if (res.length === 0) {
return;
}
console.log(res, 'res-----------')
that.mpointList = res
.filter((item) => item.report_sortstr !== "" && item.mgroup_name !== '生活区')
.map((item) => item.id); // 提取 id
}).then(() => {
// 根据 type 设置 obj 的值
if (that.query.type === 0) { // 日
arr = that.query.day.split('-');
obj.year = Number(arr[0]);
obj.month = Number(arr[1]);
obj.day = Number(arr[2]);
} else if (that.query.type === 1) { // 月
arr = that.query.month.split('-');
obj.year = Number(arr[0]);
obj.month = Number(arr[1]);
obj.days = new Date(that.query.year, that.query.month, 0).getDate(); // 获取该月的天数
} else if (that.query.type === 2) { // 年
obj.year = that.query.year;
} else if (that.query.type === 3) { // 时间范围
obj.start_time = that.daterange[0];
obj.end_time = that.daterange[1];
}
console.log(that.mpointList.length, 'that.mpointList')
let mpointID = that.mpointList.join(',');
obj.page = 0;
obj.type = 'hour';
obj.group_by = 'val_level';
obj.mpoint__in = mpointID;
this.$API.enm.mpointstat.groupValues.req(obj)
.then((res) => {
const groupedData = res.reduce((acc, item) => {
// 查找是否已有当前 mpoint__name 的分组
let group = acc.find(g => g.mpoint__name === item.mpoint__name);
// 如果没有,创建一个新的分组对象
if (!group) {
group = {
mpoint__name: item.mpoint__name,
unit: item.mpoint__unit,
flat: null,
high: null,
low: null,
peak: null,
deep: null,
};
acc.push(group);
}
// 根据 val_level 将 total_val 填入对应字段
group[item.val_level] = (item.total_val.toFixed(2));
return acc;
}, []);
this.tableData = groupedData;
console.log("groupedData",groupedData)
})
.catch((error) => {
console.error("API 请求错误: ", error);
});
});
},
// 显示图表
showBarChart(){
this.isChartDialogVisible = true;
this.$nextTick(() => {
this.createBarChart();
});
},
onDialogClose() {
this.isChartDialogVisible = false;
},
// 用于生成柱状图的函数
createBarChart() {
// 获取图表容器
let chartDom = document.getElementById('barChart');
if (!chartDom) {
console.error('无法找到 #barChart 元素');
return;
}
let myChart = echarts.init(chartDom);
// 准备数据
let seriesData = [
{ name: '平谷', data: [] },
{ name: '波峰', data: [] },
{ name: '波谷', data: [] },
{ name: '尖峰', data: [] },
{ name: '深谷', data: [] }
];
let categories = this.tableData.map(item => item.mpoint__name); // 横轴设备名称
this.tableData.forEach(item => {
seriesData[0].data.push(item.flat ? parseFloat(item.flat) : 0); // 平谷
seriesData[1].data.push(item.high ? parseFloat(item.high) : 0); // 波峰
seriesData[2].data.push(item.low ? parseFloat(item.low) : 0); // 波谷
seriesData[3].data.push(item.peak ? parseFloat(item.peak) : 0); // 尖峰
seriesData[4].data.push(item.deep ? parseFloat(item.deep) : 0); // 深谷
});
// 配置图表选项
let option = {
title: {
text: '电量统计柱状图',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' } // 鼠标悬停提示
},
legend: {
data: this.row_translate, // 显示 'peak', 'high' 等级别的图例
top: '10%'
},
xAxis: {
type: 'category',
data: categories, // 横轴设备名称
axisLabel: {
rotate: 45 // 旋转标签,防止重叠
}
},
yAxis: {
type: 'value',
axisLabel: {
formatter: '{value} kW·h' // 单位为 kW·h
}
},
series: seriesData.map(item => ({
name: item.name,
type: 'bar',
data: item.data, // 数据数组
label: {
show: true,
position: 'top',
formatter: '{c}' // 显示数值
}
}))
};
// 设置图表选项
myChart.setOption(option);
},
handlePrint() {
this.$PRINT('#myReport');
},
exportExcel() {
this.exportLoading = true;
this.$XLSX('#myTable', this.tableName)
this.exportLoading = false;
},
}
};
</script>
<style>
#numTable{
margin-left: 37px;
}
#numTable td{
height: 32px;
padding-left: 5px;
}
.numCell{
width: 80px;
}
.numCell.numCell_last{
width: 100px;
}
.searchHead{
display:flex
}
.middleText{
height: 32px;
line-height: 32px;
margin: 0 5px;
display: inline-block;
}
.searchBtn{
margin-left: 5px;
}
.myTable td:first-child {
width: 150px !important; /* 使用 !important 确保优先级足够高 */
}
</style>