1.一周充放曲线改为了时间聚合柱状图。
2.PCS最高温度修复bug展示多PCS设备的数据 3.PCS的状态根据状态枚举映射配置的内容显示 4.BMS的总览,增加工作状态、与PCS通讯、与EMS通讯的配置,及关联展示 5.增加批量导入单体电池点位的功能 6.修复计算点可能会出现id与code在一个池子内的问题,再次计算后数据正常 7.计算点增加小数位限制的功能,实时计算与7天历史接口都已经按照配置的小数位进行限制 8.统计报表中的功率曲线改为了按照分钟显示 9.功率曲线出现断点的问题是因为数据计算太密集了导致的,增加了前端连线不断的显示 10.PCS和电池堆的曲线与配置增加了关联设备显示 11.点位映射中的电池温度,增加了多设备 12.收益报表增加升序排列,合并当月所有合计 13.增加业务报表备注功能,可以根据业务设计开发,目前电表报表与收益报表均有备注列可以修改
This commit is contained in:
@ -1,18 +1,17 @@
|
||||
<template>
|
||||
<div style="width:100%" v-loading="loading">
|
||||
<!-- 搜索栏-->
|
||||
<el-form :inline="true" class="select-container">
|
||||
<el-form-item label="时间选择">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
:clearable="false"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDateRange"
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
:clearable="false"
|
||||
:picker-options="pickerOptions"
|
||||
:default-value="defaultDateRange"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@ -25,121 +24,77 @@
|
||||
<el-button type="primary" @click="exportTable" native-type="button">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!--表格-->
|
||||
|
||||
<el-table
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
show-summary
|
||||
stripe
|
||||
style="width: 100%;margin-top:25px;">
|
||||
<!-- 汇总列-->
|
||||
class="common-table"
|
||||
:data="tableData"
|
||||
:summary-method="getSummaries"
|
||||
show-summary
|
||||
stripe
|
||||
style="width: 100%; margin-top: 25px;"
|
||||
>
|
||||
<el-table-column label="汇总" min-width="100px" align="center">
|
||||
<el-table-column
|
||||
prop="dataTime"
|
||||
label="日期"
|
||||
min-width="100px" align="center">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="dayType"
|
||||
label="日期类型"
|
||||
min-width="100px" align="center">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="weatherDesc"
|
||||
label="天气情况"
|
||||
min-width="180px"
|
||||
align="center">
|
||||
</el-table-column>
|
||||
<el-table-column prop="dataTime" label="日期" min-width="100px" align="center"></el-table-column>
|
||||
<el-table-column prop="dayType" label="日期类型" min-width="100px" align="center"></el-table-column>
|
||||
<el-table-column prop="weatherDesc" label="天气情况" min-width="180px" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
|
||||
<el-table-column label="充电价格" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activePeakPrice"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeHighPrice"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeFlatPrice"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeValleyPrice"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="activeTotalPrice"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="activePeakPrice" label="尖"></el-table-column>
|
||||
<el-table-column align="center" prop="activeHighPrice" label="峰"></el-table-column>
|
||||
<el-table-column align="center" prop="activeFlatPrice" label="平"></el-table-column>
|
||||
<el-table-column align="center" prop="activeValleyPrice" label="谷"></el-table-column>
|
||||
<el-table-column align="center" prop="activeTotalPrice" label="总"></el-table-column>
|
||||
</el-table-column>
|
||||
<!--充电量列-->
|
||||
|
||||
<el-table-column label="放电价格" align="center">
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActivePeakPrice"
|
||||
label="尖">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveHighPrice"
|
||||
label="峰">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveFlatPrice"
|
||||
label="平">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveValleyPrice"
|
||||
label="谷">
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
prop="reActiveTotalPrice"
|
||||
label="总">
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="reActivePeakPrice" label="尖"></el-table-column>
|
||||
<el-table-column align="center" prop="reActiveHighPrice" label="峰"></el-table-column>
|
||||
<el-table-column align="center" prop="reActiveFlatPrice" label="平"></el-table-column>
|
||||
<el-table-column align="center" prop="reActiveValleyPrice" label="谷"></el-table-column>
|
||||
<el-table-column align="center" prop="reActiveTotalPrice" label="总"></el-table-column>
|
||||
</el-table-column>
|
||||
<!-- 实际收益-->
|
||||
<el-table-column label="" align="center" fixed="right">
|
||||
<el-table-column
|
||||
prop="actualRevenue"
|
||||
label="实际收益"
|
||||
align="center">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="" align="center">
|
||||
<el-table-column prop="actualRevenue" label="实际收益" align="center"></el-table-column>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="备注" align="center" fixed="right" min-width="260">
|
||||
<template slot-scope="scope">
|
||||
<div class="remark-cell">
|
||||
<span class="remark-text">{{ scope.row.remark || "-" }}</span>
|
||||
<el-button type="text" @click="editRemark(scope.row)">编辑</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
v-show="tableData.length>0"
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="pageNum"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 30, 40]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="totalSize"
|
||||
style="margin-top:15px;text-align: center"
|
||||
v-show="tableData.length > 0"
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:current-page="pageNum"
|
||||
:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 30, 40]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="totalSize"
|
||||
style="margin-top: 15px; text-align: center"
|
||||
>
|
||||
</el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import getQuerySiteId from "@/mixins/ems/getQuerySiteId";
|
||||
import {getAmmeterRevenueData} from '@/api/ems/dzjk'
|
||||
import {formatDate} from "@/filters/ems";
|
||||
import { batchGetBizRemark, getAmmeterRevenueData, saveBizRemark } from "@/api/ems/dzjk";
|
||||
import { formatDate } from "@/filters/ems";
|
||||
|
||||
const BIZ_TYPE = "stats_report";
|
||||
const REPORT_KEY = "SYBB";
|
||||
|
||||
export default {
|
||||
name: 'DzjkTjbbSybb',
|
||||
name: "DzjkTjbbSybb",
|
||||
mixins: [getQuerySiteId],
|
||||
data() {
|
||||
return {
|
||||
@ -149,81 +104,189 @@ export default {
|
||||
return time.getTime() > Date.now();
|
||||
},
|
||||
},
|
||||
defaultDateRange: [],//默认展示的时间
|
||||
defaultDateRange: [],
|
||||
dateRange: [],
|
||||
tableData: [],
|
||||
pageSize: 10,//分页栏当前每个数据总数
|
||||
pageNum: 1,//分页栏当前页数
|
||||
totalSize: 0,//table表格数据总数
|
||||
}
|
||||
summaryTotals: {},
|
||||
pageSize: 10,
|
||||
pageNum: 1,
|
||||
totalSize: 0,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 导出表格
|
||||
buildRemarkKey(dataTime) {
|
||||
return `${this.siteId}_${dataTime || ""}`;
|
||||
},
|
||||
loadRemarks(rows) {
|
||||
if (!rows.length) return Promise.resolve({});
|
||||
return batchGetBizRemark({
|
||||
bizType: BIZ_TYPE,
|
||||
bizKey1: REPORT_KEY,
|
||||
bizKey2List: rows.map(row => this.buildRemarkKey(row.dataTime)),
|
||||
}).then(response => response?.data || {});
|
||||
},
|
||||
applyRemarks(rows, remarkMap) {
|
||||
rows.forEach(row => {
|
||||
this.$set(row, "remark", remarkMap[this.buildRemarkKey(row.dataTime)] || "");
|
||||
});
|
||||
},
|
||||
toScaledInt(value) {
|
||||
const num = Number(value);
|
||||
return Number.isFinite(num) ? Math.round(num * 1000) : 0;
|
||||
},
|
||||
sumRowsByProp(rows, prop) {
|
||||
const total = (rows || []).reduce((sum, row) => sum + this.toScaledInt(row?.[prop]), 0);
|
||||
return total / 1000;
|
||||
},
|
||||
formatSummaryNumber(value) {
|
||||
const num = Number(value);
|
||||
if (!Number.isFinite(num)) return "";
|
||||
return num.toFixed(3).replace(/\.?0+$/, "");
|
||||
},
|
||||
buildSummaryTotals(rows) {
|
||||
const numericProps = [
|
||||
"activePeakPrice",
|
||||
"activeHighPrice",
|
||||
"activeFlatPrice",
|
||||
"activeValleyPrice",
|
||||
"activeTotalPrice",
|
||||
"reActivePeakPrice",
|
||||
"reActiveHighPrice",
|
||||
"reActiveFlatPrice",
|
||||
"reActiveValleyPrice",
|
||||
"reActiveTotalPrice",
|
||||
"actualRevenue",
|
||||
];
|
||||
return numericProps.reduce((result, prop) => {
|
||||
result[prop] = this.sumRowsByProp(rows, prop);
|
||||
return result;
|
||||
}, {});
|
||||
},
|
||||
getSummaries({ columns, data }) {
|
||||
return columns.map((column, index) => {
|
||||
if (index === 0) return "合计";
|
||||
const prop = column.property;
|
||||
if (!prop) return "";
|
||||
if (Object.prototype.hasOwnProperty.call(this.summaryTotals, prop)) {
|
||||
return this.formatSummaryNumber(this.summaryTotals[prop]);
|
||||
}
|
||||
const hasNumericValue = (data || []).some(item => Number.isFinite(Number(item?.[prop])));
|
||||
return hasNumericValue ? this.formatSummaryNumber(this.sumRowsByProp(data, prop)) : "";
|
||||
});
|
||||
},
|
||||
exportTable() {
|
||||
if (!this.dateRange?.length) return
|
||||
const [startTime, endTime] = this.dateRange
|
||||
this.download('ems/statsReport/exportAmmeterRevenueData', {
|
||||
siteId: this.siteId,
|
||||
startTime,
|
||||
endTime,
|
||||
}, `收益报表_${startTime}-${endTime}.xlsx`)
|
||||
if (!this.dateRange?.length) return;
|
||||
const [startTime, endTime] = this.dateRange;
|
||||
this.download(
|
||||
"ems/statsReport/exportAmmeterRevenueData",
|
||||
{
|
||||
siteId: this.siteId,
|
||||
startTime,
|
||||
endTime,
|
||||
},
|
||||
`收益报表_${startTime}-${endTime}.xlsx`
|
||||
);
|
||||
},
|
||||
// 搜索
|
||||
onSearch() {
|
||||
this.pageNum = 1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
this.pageNum = 1;
|
||||
this.getData();
|
||||
},
|
||||
// 重置
|
||||
onReset() {
|
||||
this.dateRange = this.defaultDateRange
|
||||
this.pageNum = 1//每次搜索从1开始搜索
|
||||
this.getData()
|
||||
this.dateRange = this.defaultDateRange;
|
||||
this.pageNum = 1;
|
||||
this.getData();
|
||||
},
|
||||
// 分页
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
this.$nextTick(() => {
|
||||
this.getData()
|
||||
})
|
||||
this.getData();
|
||||
});
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pageNum = val
|
||||
this.pageNum = val;
|
||||
this.$nextTick(() => {
|
||||
this.getData()
|
||||
})
|
||||
this.getData();
|
||||
});
|
||||
},
|
||||
// 获取数据
|
||||
getData() {
|
||||
this.loading = true
|
||||
const {siteId, pageNum, pageSize} = this
|
||||
const [startTime = '', endTime = ''] = (this.dateRange || [])
|
||||
getAmmeterRevenueData({siteId: siteId, startTime, endTime, pageSize, pageNum}).then(response => {
|
||||
const rows = response?.rows || [];
|
||||
this.totalSize = response?.total || 0
|
||||
this.tableData = rows
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
editRemark(row) {
|
||||
this.$prompt("请输入备注", "编辑备注", {
|
||||
inputValue: row.remark || "",
|
||||
inputType: "textarea",
|
||||
inputPlaceholder: "可输入该日报表备注",
|
||||
confirmButtonText: "保存",
|
||||
cancelButtonText: "取消",
|
||||
})
|
||||
.then(({ value }) => {
|
||||
return saveBizRemark({
|
||||
bizType: BIZ_TYPE,
|
||||
bizKey1: REPORT_KEY,
|
||||
bizKey2: this.buildRemarkKey(row.dataTime),
|
||||
remark: value || "",
|
||||
}).then(() => {
|
||||
this.$set(row, "remark", value || "");
|
||||
this.$message.success("备注保存成功");
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
getData() {
|
||||
this.loading = true;
|
||||
const { siteId, pageNum, pageSize } = this;
|
||||
const [startTime = "", endTime = ""] = this.dateRange || [];
|
||||
|
||||
getAmmeterRevenueData({ siteId, startTime, endTime, pageSize, pageNum })
|
||||
.then(pageResponse => {
|
||||
const rows = pageResponse?.rows || [];
|
||||
const total = Number(pageResponse?.total || 0);
|
||||
this.totalSize = total;
|
||||
this.tableData = rows;
|
||||
|
||||
const tasks = [this.loadRemarks(rows)];
|
||||
if (total > 0) {
|
||||
tasks.push(
|
||||
getAmmeterRevenueData({
|
||||
siteId,
|
||||
startTime,
|
||||
endTime,
|
||||
pageNum: 1,
|
||||
pageSize: total,
|
||||
})
|
||||
);
|
||||
}
|
||||
return Promise.all(tasks);
|
||||
})
|
||||
.then(([remarkMap, allResponse]) => {
|
||||
this.applyRemarks(this.tableData, remarkMap || {});
|
||||
const allRows = allResponse?.rows || allResponse?.data || [];
|
||||
this.summaryTotals = this.buildSummaryTotals(allRows);
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.dateRange = []
|
||||
this.tableData = []
|
||||
this.totalSize = 0
|
||||
this.pageSize = 10
|
||||
this.pageNum = 1
|
||||
let now = new Date(), lastDay = now.getTime(), firstDay = new Date(now.setDate(1)).getTime();
|
||||
this.dateRange = [];
|
||||
this.tableData = [];
|
||||
this.summaryTotals = {};
|
||||
this.totalSize = 0;
|
||||
this.pageSize = 10;
|
||||
this.pageNum = 1;
|
||||
const now = new Date();
|
||||
const lastDay = now.getTime();
|
||||
const firstDay = new Date(new Date().setDate(1)).getTime();
|
||||
this.defaultDateRange = [formatDate(firstDay), formatDate(lastDay)];
|
||||
this.dateRange = [formatDate(firstDay), formatDate(lastDay)];
|
||||
this.getData()
|
||||
this.getData();
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep {
|
||||
.common-table.el-table {
|
||||
.el-table__header-wrapper th, .common-table.el-table .el-table__fixed-header-wrapper th {
|
||||
.el-table__header-wrapper th,
|
||||
.common-table.el-table .el-table__fixed-header-wrapper th {
|
||||
border-bottom: 1px solid #dfe6ec;
|
||||
}
|
||||
|
||||
@ -234,7 +297,20 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.remark-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.remark-text {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user