296 lines
8.2 KiB
Vue
296 lines
8.2 KiB
Vue
<template>
|
|
<div class="year-data">
|
|
<el-row :gutter="10">
|
|
<el-col :span="6" style="margin-top: 10px; margin-bottom: 10px">
|
|
<dept-tree @deptChange="handleDeptChange" :showQuickGroup="true" />
|
|
</el-col>
|
|
<el-col :span="6" style="margin-top: 10px; margin-bottom: 10px">
|
|
<el-date-picker
|
|
v-model="year"
|
|
type="year"
|
|
format="yyyy"
|
|
value-format="yyyy"
|
|
placeholder="选择年"
|
|
@change="handleYearChange"
|
|
>
|
|
</el-date-picker>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<div class="export_btn">
|
|
<el-button
|
|
type="primary"
|
|
icon="eel-icon-download"
|
|
@click="handleExport"
|
|
>导出</el-button
|
|
>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-table
|
|
:data="tableData"
|
|
style="width: 100%"
|
|
border
|
|
:span-method="objectSpanMethod"
|
|
:row-class-name="tableRowClassName"
|
|
v-loading="loading"
|
|
>
|
|
<el-table-column prop="ppp" label="归属港口">
|
|
<template slot-scope="{ row }">
|
|
<div>{{ row.ppp }}</div>
|
|
<div style="display: flex; gap: 10px">
|
|
<el-tag>港区数: {{ getChildCount(row, "ppp", "pp") }}</el-tag>
|
|
<el-tag type="warning"
|
|
>平均值: {{ calculateChildAvg(row, "ppp") }} mg/m³</el-tag
|
|
>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="pp" label="归属港区">
|
|
<template slot-scope="{ row }">
|
|
<div>{{ row.pp }}</div>
|
|
<div style="display: flex; gap: 10px">
|
|
<el-tag>企业数: {{ getChildCount(row, "pp", "p") }}</el-tag>
|
|
<el-tag type="warning"
|
|
>平均值: {{ calculateChildAvg(row, "pp") }} mg/m³</el-tag
|
|
>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="p" label="归属企业">
|
|
<template slot-scope="{ row }">
|
|
<div>{{ row.p }}</div>
|
|
<div style="display: flex; gap: 10px">
|
|
<el-tag>设备数: {{ getChildCount(row, "p", "sn") }}</el-tag>
|
|
<el-tag type="warning"
|
|
>平均值: {{ calculateChildAvg(row, "p") }} mg/m³</el-tag
|
|
>
|
|
</div>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="name" label="设备名称" />
|
|
<!-- <el-table-column prop="year" label="年份" /> -->
|
|
<el-table-column prop="avgValue" label="平均值">
|
|
<template slot-scope="{ row }">
|
|
<div>{{ row.avgValue }} mg/m³</div>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<!-- <div class="page-ele">
|
|
<el-pagination
|
|
layout="sizes, prev, pager, next, total"
|
|
:total="total"
|
|
:page-size="pageSize"
|
|
:page-sizes="[10, 20, 30, 40]"
|
|
@current-change="handleCurrentChange"
|
|
@size-change="handleSizeChange"
|
|
>
|
|
</el-pagination>
|
|
</div> -->
|
|
</el-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { debounce } from "@/utils";
|
|
import moment from "moment";
|
|
import {
|
|
getDeviceReportYearList,
|
|
getDeviceReportYearListAll,
|
|
} from "@/api/statistics/yearData.js";
|
|
import { dataToExcel } from "@/utils/excel.js";
|
|
import to from "@/utils/await-to.js";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
dept: null,
|
|
year: "",
|
|
queryDebounce: null,
|
|
tableData: [],
|
|
total: 0,
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
loading: false,
|
|
};
|
|
},
|
|
computed: {
|
|
tableHeight() {
|
|
return window.innerHeight - 300;
|
|
},
|
|
pppList() {
|
|
return Array.from(new Set(this.tableData.map((item) => item.ppp)));
|
|
},
|
|
},
|
|
mounted() {
|
|
// 获取当前年份 2024
|
|
this.year = moment().year().toString();
|
|
this.queryDebounce = debounce(this.query, 100);
|
|
},
|
|
methods: {
|
|
tableRowClassName({ row, rowIndex }) {
|
|
const classNames = [
|
|
"default-row",
|
|
"success-row",
|
|
"error-row",
|
|
"warning-row",
|
|
"info-row",
|
|
];
|
|
const index = this.pppList.findIndex((item) => item === row.ppp);
|
|
if (index === -1) return "info-row";
|
|
return index > classNames.length - 1
|
|
? classNames[index % classNames.length]
|
|
: classNames[index];
|
|
},
|
|
getChildCount(row, key, childKey) {
|
|
const childSet = new Set();
|
|
for (let i = 0; i < this.tableData.length; i++) {
|
|
if (row[key] === this.tableData[i][key]) {
|
|
childSet.add(this.tableData[i][childKey]);
|
|
}
|
|
}
|
|
return childSet.size;
|
|
},
|
|
calculateChildAvg(row, key) {
|
|
const childList = [];
|
|
for (let i = 0; i < this.tableData.length; i++) {
|
|
if (row[key] === this.tableData[i][key]) {
|
|
childList.push(this.tableData[i].avgValue);
|
|
}
|
|
}
|
|
// 计算平均值, 保留两位小数
|
|
return (childList.reduce((a, b) => a + b, 0) / childList.length).toFixed(
|
|
2
|
|
);
|
|
},
|
|
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
const calculateRowSpan = (key) => {
|
|
const value = row[key];
|
|
let rowSpan = 1;
|
|
if (rowIndex === 0) {
|
|
while (
|
|
this.tableData[rowIndex + rowSpan] &&
|
|
this.tableData[rowIndex + rowSpan][key] === value
|
|
) {
|
|
rowSpan++;
|
|
}
|
|
return { rowspan: rowSpan, colspan: 1 };
|
|
} else {
|
|
if (this.tableData[rowIndex - 1][key] === value) {
|
|
return { rowspan: 0, colspan: 0 };
|
|
} else {
|
|
while (
|
|
this.tableData[rowIndex + rowSpan] &&
|
|
this.tableData[rowIndex + rowSpan][key] === value
|
|
) {
|
|
rowSpan++;
|
|
}
|
|
return { rowspan: rowSpan, colspan: 1 };
|
|
}
|
|
}
|
|
};
|
|
|
|
if (columnIndex === 0) {
|
|
return calculateRowSpan("ppp");
|
|
} else if (columnIndex === 1) {
|
|
return calculateRowSpan("pp");
|
|
} else if (columnIndex === 2) {
|
|
return calculateRowSpan("p");
|
|
}
|
|
},
|
|
handleYearChange() {
|
|
this.queryDebounce();
|
|
},
|
|
handleDeptChange(dept) {
|
|
this.dept = dept;
|
|
this.queryDebounce();
|
|
},
|
|
handleCurrentChange(val) {
|
|
this.pageNum = val;
|
|
this.queryDebounce();
|
|
},
|
|
handleSizeChange(val) {
|
|
this.pageSize = val;
|
|
this.queryDebounce();
|
|
},
|
|
query() {
|
|
if (!this.dept || !this.year) {
|
|
return;
|
|
}
|
|
this.loading = true;
|
|
|
|
getDeviceReportYearListAll({
|
|
deptId: this.dept.deptId,
|
|
year: this.year,
|
|
// pageNum: this.pageNum,
|
|
// pageSize: this.pageSize,
|
|
})
|
|
.then((res) => {
|
|
if (res.code === 200) {
|
|
this.tableData = res.data.map((item) => {
|
|
return {
|
|
...item,
|
|
avgValue: parseFloat(item.avgValue.toFixed(2)),
|
|
};
|
|
});
|
|
// this.total = res.total;
|
|
}
|
|
})
|
|
.finally(() => {
|
|
this.loading = false;
|
|
});
|
|
},
|
|
async handleExport() {
|
|
const fileName = `${this.dept.deptName} ${this.year}年数据统计`;
|
|
const [err, response] = await to(
|
|
getDeviceReportYearListAll({
|
|
deptId: this.dept.deptId,
|
|
year: this.year,
|
|
})
|
|
);
|
|
if (err) {
|
|
console.error(err);
|
|
this.$message.error("导出失败");
|
|
return;
|
|
}
|
|
const { data } = response;
|
|
dataToExcel({
|
|
data: [
|
|
[fileName],
|
|
["归属港口", "归属港区", "归属企业", "设备编码", "年份", "平均值"],
|
|
...data.map((row) => [
|
|
row.ppp,
|
|
row.pp,
|
|
row.p,
|
|
row.sn,
|
|
row.year,
|
|
row.avgValue,
|
|
]),
|
|
],
|
|
fileName,
|
|
wsCallback: (ws) => {
|
|
if (!ws["!merges"]) ws["!merges"] = [];
|
|
ws["!merges"].push({ s: { r: 0, c: 0 }, e: { r: 0, c: 4 } });
|
|
},
|
|
});
|
|
this.$message.success("导出成功");
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.year-data {
|
|
padding: 10px 20px;
|
|
}
|
|
.export_btn {
|
|
margin-top: 10px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
.page-ele {
|
|
margin-top: 10px;
|
|
text-align: right;
|
|
}
|
|
</style>
|