<template>
|
<div class="app-container">
|
<!-- 搜索区域 -->
|
<div class="search_form">
|
<el-form :model="searchForm"
|
:inline="true">
|
<el-form-item label="年份:">
|
<el-select v-model="searchForm.year"
|
placeholder="请选择年份"
|
style="width: 120px;"
|
@change="handleQuery">
|
<el-option v-for="year in years"
|
:key="year"
|
:label="year + '年'"
|
:value="year" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="能耗类型:">
|
<el-select v-model="searchForm.energyType"
|
placeholder="全部"
|
clearable
|
style="width: 140px;"
|
@change="handleQuery">
|
<el-option label="全部"
|
value="全部" />
|
<el-option label="水"
|
value="水" />
|
<el-option label="电"
|
value="电" />
|
<el-option label="蒸汽"
|
value="蒸汽" />
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary"
|
@click="handleQuery">查询</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<div>
|
<el-button type="success"
|
@click="handleExport">导出报表</el-button>
|
</div>
|
</div>
|
<!-- 图表区域 -->
|
<div class="chart-section">
|
<h2 class="section-header">
|
<el-icon class="header-icon">
|
<TrendCharts />
|
</el-icon>
|
能耗单耗趋势
|
</h2>
|
<div class="chart-card">
|
<div ref="consumptionChart"
|
class="chart-content"></div>
|
</div>
|
</div>
|
<!-- 数据表格 -->
|
<div class="table-section">
|
<h2 class="section-header">
|
<el-icon class="header-icon">
|
<List />
|
</el-icon>
|
能耗单耗数据
|
</h2>
|
<el-table :data="tableData"
|
v-loading="tableLoading"
|
border>
|
<el-table-column prop="energyType"
|
label="能耗"
|
width="100"
|
align="center">
|
<template #default="scope">
|
<el-tag :type="getEnergyTypeType(scope.row.energyType)">
|
{{ scope.row.energyType }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="unit"
|
label="单位"
|
width="120"
|
align="center" />
|
<el-table-column label="月度数据">
|
<el-table-column prop="monthlyUnitConsumption"
|
label="月度累计单耗"
|
align="right">
|
<template #default="scope">
|
<span class="data-value">{{ scope.row.monthlyUnitConsumption }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="monthlyConsumption"
|
label="月度累计用量/月度累计产量"
|
align="right">
|
<template #default="scope">
|
<span class="data-value">{{ scope.row.monthlyConsumption }}/{{ scope.row.monthlyProduction }}</span>
|
</template>
|
</el-table-column>
|
</el-table-column>
|
<el-table-column label="年度数据">
|
<el-table-column prop="annualUnitConsumption"
|
label="年度累计单耗"
|
align="right">
|
<template #default="scope">
|
<span class="data-value">{{ scope.row.annualUnitConsumption }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="annualConsumption"
|
label="年度累计用量/年度累计产量"
|
align="right">
|
<template #default="scope">
|
<span class="data-value">{{ scope.row.annualConsumption }}/{{ scope.row.annualProduction }}</span>
|
</template>
|
</el-table-column>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted, nextTick } from "vue";
|
import { ElMessage } from "element-plus";
|
import { TrendCharts, List } from "@element-plus/icons-vue";
|
import * as echarts from "echarts";
|
|
// 搜索表单
|
const searchForm = reactive({
|
year: new Date().getFullYear(),
|
energyType: "",
|
});
|
|
// 生成年份选项
|
const years = [];
|
const currentYear = new Date().getFullYear();
|
for (let i = currentYear - 5; i <= currentYear; i++) {
|
years.push(i);
|
}
|
|
// 表格数据
|
const tableData = ref([]);
|
const tableLoading = ref(false);
|
|
// 图表引用
|
const consumptionChart = ref(null);
|
let consumptionChartInstance = null;
|
|
// 获取能耗类型标签类型
|
const getEnergyTypeType = type => {
|
const typeMap = {
|
水: "primary",
|
电: "warning",
|
蒸汽: "success",
|
};
|
return typeMap[type] || "info";
|
};
|
|
// 初始化图表
|
const initChart = () => {
|
nextTick(() => {
|
if (consumptionChart.value) {
|
consumptionChartInstance = echarts.init(consumptionChart.value);
|
updateChart();
|
}
|
});
|
};
|
|
// 更新图表
|
const updateChart = () => {
|
const data = tableData.value;
|
const months = [
|
"1月",
|
"2月",
|
"3月",
|
"4月",
|
"5月",
|
"6月",
|
"7月",
|
"8月",
|
"9月",
|
"10月",
|
"11月",
|
"12月",
|
];
|
|
// 准备图表数据
|
const series = [];
|
const energyTypes = ["水", "电", "蒸汽"];
|
|
energyTypes.forEach(type => {
|
const typeData = data.find(item => item.energyType === type);
|
if (typeData && typeData.monthlyData) {
|
series.push({
|
name: type,
|
type: "line",
|
data: typeData.monthlyData.map(item => item.unitConsumption),
|
smooth: true,
|
symbol: "circle",
|
symbolSize: 8,
|
lineStyle: {
|
width: 3,
|
},
|
itemStyle: {
|
color:
|
getEnergyTypeType(type) === "primary"
|
? "#409EFF"
|
: getEnergyTypeType(type) === "warning"
|
? "#E6A23C"
|
: "#67C23A",
|
},
|
});
|
}
|
});
|
|
const option = {
|
tooltip: {
|
trigger: "axis",
|
backgroundColor: "rgba(255, 255, 255, 0.95)",
|
borderColor: "#409EFF",
|
borderWidth: 1,
|
textStyle: { color: "#303133" },
|
},
|
legend: {
|
data: energyTypes,
|
top: 0,
|
right: 10,
|
textStyle: { color: "#606266" },
|
},
|
grid: {
|
left: "3%",
|
right: "4%",
|
bottom: "10%",
|
top: "15%",
|
containLabel: true,
|
},
|
xAxis: {
|
type: "category",
|
data: months,
|
axisLabel: { color: "#606266" },
|
axisLine: { lineStyle: { color: "#ebeef5" } },
|
splitLine: { show: false },
|
},
|
yAxis: {
|
type: "value",
|
name: "单耗",
|
nameTextStyle: { color: "#606266" },
|
axisLabel: { color: "#606266" },
|
axisLine: { show: false },
|
splitLine: { lineStyle: { color: "#f0f2f5" } },
|
},
|
series: series,
|
};
|
|
consumptionChartInstance.setOption(option);
|
};
|
|
// 查询
|
const handleQuery = () => {
|
tableLoading.value = true;
|
|
// 模拟接口调用
|
setTimeout(() => {
|
generateMockData();
|
tableLoading.value = false;
|
updateChart();
|
}, 500);
|
};
|
|
// 重置
|
const handleReset = () => {
|
searchForm.year = new Date().getFullYear();
|
searchForm.energyType = "";
|
handleQuery();
|
};
|
|
// 导出
|
const handleExport = () => {
|
ElMessage.success("报表导出成功");
|
};
|
|
// 生成假数据
|
const generateMockData = () => {
|
const energyTypes = [
|
{
|
energyType: "水",
|
unit: "吨/立方米",
|
monthlyUnitConsumption: (Math.random() * 0.5 + 0.8).toFixed(4),
|
monthlyConsumption: Math.floor(Math.random() * 5000 + 10000),
|
monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
|
annualUnitConsumption: (Math.random() * 0.3 + 0.9).toFixed(4),
|
annualConsumption: Math.floor(Math.random() * 60000 + 120000),
|
annualProduction: Math.floor(Math.random() * 120000 + 240000),
|
monthlyData: generateMonthlyData(0.8, 1.3),
|
},
|
{
|
energyType: "电",
|
unit: "度/立方米",
|
monthlyUnitConsumption: (Math.random() * 2 + 5).toFixed(4),
|
monthlyConsumption: Math.floor(Math.random() * 50000 + 100000),
|
monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
|
annualUnitConsumption: (Math.random() * 1.5 + 5.5).toFixed(4),
|
annualConsumption: Math.floor(Math.random() * 600000 + 1200000),
|
annualProduction: Math.floor(Math.random() * 120000 + 240000),
|
monthlyData: generateMonthlyData(5, 7),
|
},
|
{
|
energyType: "蒸汽",
|
unit: "吨/立方米",
|
monthlyUnitConsumption: (Math.random() * 0.3 + 0.5).toFixed(4),
|
monthlyConsumption: Math.floor(Math.random() * 3000 + 6000),
|
monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
|
annualUnitConsumption: (Math.random() * 0.2 + 0.55).toFixed(4),
|
annualConsumption: Math.floor(Math.random() * 36000 + 72000),
|
annualProduction: Math.floor(Math.random() * 120000 + 240000),
|
monthlyData: generateMonthlyData(0.5, 0.8),
|
},
|
];
|
|
if (searchForm.energyType && searchForm.energyType !== "全部") {
|
tableData.value = energyTypes.filter(
|
item => item.energyType === searchForm.energyType
|
);
|
} else {
|
tableData.value = energyTypes;
|
}
|
};
|
|
// 生成月度数据
|
const generateMonthlyData = (min, max) => {
|
const data = [];
|
for (let i = 1; i <= 12; i++) {
|
data.push({
|
month: i,
|
unitConsumption: (Math.random() * (max - min) + min).toFixed(4),
|
});
|
}
|
return data;
|
};
|
|
// 窗口大小变化时重新渲染图表
|
const handleResize = () => {
|
consumptionChartInstance && consumptionChartInstance.resize();
|
};
|
|
onMounted(() => {
|
handleQuery();
|
initChart();
|
window.addEventListener("resize", handleResize);
|
});
|
</script>
|
|
<style scoped lang="scss">
|
.app-container {
|
padding: 20px;
|
}
|
|
.search_form {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding: 15px;
|
background-color: #f5f7fa;
|
border-radius: 8px;
|
}
|
|
.chart-section {
|
margin-bottom: 30px;
|
}
|
|
.table-section {
|
margin-bottom: 20px;
|
}
|
|
.section-header {
|
display: flex;
|
align-items: center;
|
font-size: 18px;
|
font-weight: bold;
|
color: #303133;
|
margin-bottom: 15px;
|
padding-left: 10px;
|
border-left: 3px solid #409eff;
|
|
.header-icon {
|
margin-right: 8px;
|
color: #409eff;
|
}
|
}
|
|
.chart-card {
|
background: #fff;
|
border-radius: 4px;
|
border: 1px solid #ebeef5;
|
padding: 20px;
|
|
.chart-content {
|
height: 400px;
|
}
|
}
|
|
.data-value {
|
font-weight: bold;
|
color: #409eff;
|
}
|
</style>
|