247 lines
7.3 KiB
Vue
247 lines
7.3 KiB
Vue
<template>
|
||
<div>
|
||
<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="dateValue"
|
||
type="month"
|
||
format="yyyy-MM"
|
||
value-format="yyyy-MM"
|
||
placeholder="选择月份"
|
||
@change="handleDateChange"
|
||
>
|
||
</el-date-picker>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<div class="export_btn">
|
||
<el-button
|
||
type="primary"
|
||
icon="eel-icon-download"
|
||
@click="exportToExcel"
|
||
>导出</el-button
|
||
>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row :gutter="10">
|
||
<el-col :span="24">
|
||
<el-table :data="tableData" :header-cell-style="headerStyle" :loading="loading" @sort-change="sortChange">
|
||
<el-table-column
|
||
prop="gangKou"
|
||
label="港口"
|
||
align="center"
|
||
></el-table-column>
|
||
<el-table-column
|
||
prop="gangQu"
|
||
label="港区"
|
||
align="center"
|
||
></el-table-column>
|
||
<el-table-column
|
||
prop="currAvgDs"
|
||
label="本月均值"
|
||
sortable
|
||
align="center"
|
||
></el-table-column>
|
||
<el-table-column
|
||
prop="preMonthAvgDs"
|
||
label="上月均值"
|
||
sortable
|
||
align="center"
|
||
></el-table-column>
|
||
<el-table-column
|
||
prop="mom"
|
||
label="环比%"
|
||
sortable
|
||
:sortMethod="sortMomMethod"
|
||
align="center"
|
||
>
|
||
<template slot-scope="scope">
|
||
{{ scope.row.mom }}%
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="lastYearAvgDs"
|
||
label="去年同月均值"
|
||
sortable
|
||
align="center"
|
||
></el-table-column>
|
||
<el-table-column
|
||
prop="yoy"
|
||
label="同比%"
|
||
sortable
|
||
:sortMethod="sortYoyMethod"
|
||
align="center"
|
||
>
|
||
<template slot-scope="scope">
|
||
{{ scope.row.yoy }}%
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import * as XLSX from "xlsx";
|
||
import { dataDetailGangQuCompare } from "@/api/statistics/monthData.js";
|
||
export default {
|
||
name: "DataCompare",
|
||
data() {
|
||
return {
|
||
deptId: "",
|
||
deptName: "",
|
||
dateValue: "",
|
||
tableData: [],
|
||
loading: false,
|
||
headerStyle: {
|
||
fontSize: "14px",
|
||
backgroundColor: "#f8f8f8",
|
||
color: "#333",
|
||
},
|
||
};
|
||
},
|
||
created() {
|
||
this.initDate();
|
||
},
|
||
methods: {
|
||
initDate() {
|
||
const date = new Date();
|
||
const year = date.getFullYear();
|
||
const month = date.getMonth() + 1;
|
||
const monthStr = month < 10 ? `0${month}` : month;
|
||
this.dateValue = `${year}-${monthStr}`;
|
||
},
|
||
handleDeptChange(value) {
|
||
this.deptId = value.deptId;
|
||
this.deptName = value.deptName;
|
||
this.queryData();
|
||
},
|
||
handleDateChange(value) {
|
||
this.queryData();
|
||
},
|
||
sortMomMethod(a, b) {
|
||
return parseFloat(a.mom) - parseFloat(b.mom);
|
||
},
|
||
sortYoyMethod(a, b) {
|
||
return parseFloat(a.yoy) - parseFloat(b.yoy);
|
||
},
|
||
sortChange({ prop, order }) {
|
||
if (order === "ascending") {
|
||
this.tableData.sort((a, b) => a[prop] - b[prop]);
|
||
} else {
|
||
this.tableData.sort((a, b) => b[prop] - a[prop]);
|
||
}
|
||
},
|
||
queryData() {
|
||
this.tableData = [];
|
||
this.loading = true;
|
||
dataDetailGangQuCompare({
|
||
deptId: this.deptId,
|
||
month: this.dateValue,
|
||
}).then((res) => {
|
||
if (res.code === 200) {
|
||
const { currentMonthDs, lastYearDs, preMonthDs } = res.data;
|
||
// const minLength = Math.min(currentMonthDs.length, lastYearDs.length, preMonthDs.length);
|
||
// 比较三个数组的长度,得到最小的数组
|
||
// const minLength = Math.min(currentMonthDs.length, lastYearDs.length, preMonthDs.length);
|
||
// 获取本月ds均值,上月ds均值,环比%,去年同月ds均值,同比% ,同比增减
|
||
// mom 环比% = (本月均值 - 上月均值) / 上月均值 *100%
|
||
// yoy 同比% = (本月均值 - 去年同月均值) / 去年同月均值 *100%
|
||
// 同比增减=本月均值 - 去年同月均值
|
||
for (let i = 0; i < currentMonthDs.length; i++) {
|
||
const dataItem = {};
|
||
const currentMonthDsItem = currentMonthDs[i];
|
||
dataItem.gangQu = currentMonthDsItem.gangQu;
|
||
dataItem.gangKou = currentMonthDsItem.gangKou;
|
||
dataItem.currAvgDs = currentMonthDsItem.avgDs;
|
||
const lastYearDsItem = lastYearDs.find(
|
||
(item) => item.gangQu === currentMonthDsItem.gangQu
|
||
);
|
||
if (lastYearDsItem) {
|
||
dataItem.lastYearAvgDs = lastYearDsItem.avgDs;
|
||
dataItem.yoy =
|
||
(
|
||
((currentMonthDsItem.avgDs - lastYearDsItem.avgDs) /
|
||
lastYearDsItem.avgDs) *
|
||
100
|
||
).toFixed(2);
|
||
} else {
|
||
dataItem.lastYearAvgDs = 0;
|
||
dataItem.yoy = 0;
|
||
}
|
||
const preMonthDsItem = preMonthDs.find(
|
||
(item) => item.gangQu === currentMonthDsItem.gangQu
|
||
);
|
||
if (preMonthDsItem) {
|
||
dataItem.preMonthAvgDs = preMonthDsItem.avgDs;
|
||
dataItem.mom =
|
||
(
|
||
((currentMonthDsItem.avgDs - preMonthDsItem.avgDs) /
|
||
preMonthDsItem.avgDs) *
|
||
100
|
||
).toFixed(2);
|
||
} else {
|
||
dataItem.preMonthAvgDs = 0;
|
||
dataItem.mom = 0;
|
||
}
|
||
this.tableData.push(dataItem);
|
||
}
|
||
}
|
||
}).finally(() => {
|
||
this.loading = false;
|
||
});
|
||
},
|
||
exportToExcel() {
|
||
// 创建一个新的工作簿
|
||
const wb = XLSX.utils.book_new();
|
||
const filename = `${this.deptName} ${this.dateValue.replace("-", "年") + "月"} 数据详情`;
|
||
// // 创建一个新的工作表
|
||
const ws_name = "SheetJS";
|
||
const ws_data = [
|
||
[filename],
|
||
["港口", "港区", "本月均值", "上月均值", "环比%", "去年同月均值", "同比%"],
|
||
...this.tableData.map((row) => [
|
||
row.gangKou,
|
||
row.gangQu,
|
||
row.currAvgDs,
|
||
row.preMonthAvgDs,
|
||
row.mom,
|
||
row.lastYearAvgDs,
|
||
row.yoy,
|
||
]),
|
||
];
|
||
const ws = XLSX.utils.aoa_to_sheet(ws_data);
|
||
// // 合并第一行的前8列
|
||
if(!ws['!merges']) ws['!merges'] = [];
|
||
ws['!merges'].push({s: {r: 0, c: 0}, e: {r: 0, c: 7}});
|
||
// // 将工作表添加到工作簿中
|
||
XLSX.utils.book_append_sheet(wb, ws, ws_name);
|
||
XLSX.writeFile(wb, `${filename}.xlsx`);
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.table-title {
|
||
border: 1px solid #ebeef5;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 45px;
|
||
span {
|
||
font-size: 18px;
|
||
color: #333;
|
||
}
|
||
}
|
||
.export_btn {
|
||
padding: 10px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
</style>
|