1 changed files with 477 additions and 0 deletions
@ -0,0 +1,477 @@ |
|||||||
|
<template> |
||||||
|
<div class="app-container app-container-bg"> |
||||||
|
<el-card class="first-card" ref='firstCard' shadow="always"> |
||||||
|
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent> |
||||||
|
<el-form-item label="时间范围" prop="dateTime"> |
||||||
|
<el-date-picker :clearable="false" v-model="queryParams.dateTime" type="daterange" format="YYYY-MM-DD" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" popper-class="date-clear"> |
||||||
|
</el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</el-card> |
||||||
|
<div class="el-card-p card-shadow carder-border mt10 pad10 scroll-bar"> |
||||||
|
<div style="max-width:1200px;margin: 0 auto;" v-loading="loading"> |
||||||
|
<h2 class="text-center">{{queryParams.dateTime[0]}}到{{queryParams.dateTime[1]}}周报数据统计</h2> |
||||||
|
<ul style="height:98%;"> |
||||||
|
<li v-for='(item,index) in weekReportData' :key="index"> |
||||||
|
<h2>{{item.title}}</h2> |
||||||
|
<span v-if="item.stationType=='A'">总降雨量<span class="ml10 mr10">{{item.totalRain}}</span>mm</span> |
||||||
|
<span v-if="item.stationType=='T'">本周平均温度为{{item.tempAvg}}℃,最高温度为{{item.tempMax}}℃。</span> |
||||||
|
<!-- :span-method="arraySpanMethod" --> |
||||||
|
<el-table v-if="item.stationType=='A'" class="mt10 table-box double-header-table" :data="item.tableData" :span-method="arraySpanMethod"> |
||||||
|
<el-table-column label="雨量站站点" :align="alignment"> |
||||||
|
<el-table-column prop="yujingzhi" :align="alignment" /> |
||||||
|
<el-table-column prop="name" :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column :align="alignment"> |
||||||
|
<template #header> |
||||||
|
<div style="line-height: 1.2;text-align: center;"> |
||||||
|
<div>最大一小时</div> |
||||||
|
<div>降雨量(mm)</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-table-column prop="oneHourValue" :align="alignment" width="60" /> |
||||||
|
<el-table-column prop="oneHourStart" :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column> |
||||||
|
<template #header> |
||||||
|
<div style="line-height: 1.2;text-align: center;"> |
||||||
|
<div>最大三小时</div> |
||||||
|
<div>降雨量(mm)</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<el-table-column prop="threeHourValue" :align="alignment" width="60" /> |
||||||
|
<el-table-column prop="threeHourStart" :align="alignment" /> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="sessionValue" :align="alignment"> |
||||||
|
<template #header> |
||||||
|
<div style="line-height: 1.2;text-align: center;"> |
||||||
|
<div>最大场次</div> |
||||||
|
<div>降雨量(mm)</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="totalValue" :align="alignment"> |
||||||
|
<template #header> |
||||||
|
<div style="line-height: 1.2;text-align: center;"> |
||||||
|
<div>总降雨量</div> |
||||||
|
<div>(mm)</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-table v-if="item.stationType=='B'||item.stationType=='C'" class="mt10 table-box " :data="item.tableData" border> |
||||||
|
<el-table-column label="站点" prop="name" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="水位(m)" :align="alignment"> |
||||||
|
<el-table-column label="最大水位" prop="maxValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="最小水位" prop="minValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="平均水位" prop="avgValue" :align="alignment"></el-table-column> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-table v-if="item.stationType==='T'" class="mt10 table-box " :data="item.tableData" border> |
||||||
|
<el-table-column label="站点" prop="name" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="温度(℃)" :align="alignment"> |
||||||
|
<el-table-column label="最大温度" prop="maxValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="最小温度" prop="minValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="平均温度" prop="avgValue" :align="alignment"></el-table-column> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-table v-if="item.stationType==='S'" class="mt10 table-box " :data="item.tableData" border> |
||||||
|
<el-table-column label="站点" prop="name" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="风速(m/s)" :align="alignment"> |
||||||
|
<el-table-column label="最大风速" prop="maxValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="最小风速" prop="minValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="平均风速" prop="avgValue" :align="alignment"></el-table-column> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-table v-if="item.stationType==='R'" class="mt10 table-box " :data="item.tableData" border> |
||||||
|
<el-table-column label="站点" prop="name" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="湿度(%)" :align="alignment"> |
||||||
|
<el-table-column label="最大湿度" prop="maxValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="最小湿度" prop="minValue" :align="alignment"></el-table-column> |
||||||
|
<el-table-column label="平均湿度" prop="avgValue" :align="alignment"></el-table-column> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<el-table v-if="item.stationType=='U'" class="mt10 table-box " :data="item.tableData" border> |
||||||
|
<el-table-column v-for='(column, colIndex) in item.TableHeader' :key="colIndex" :label="column.stcd" :prop="column.field" :align="alignment"></el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="mt10" style="height:280px;" v-if="item.isEcharts"> |
||||||
|
<!-- 为每个图表创建独立的容器 --> |
||||||
|
<div :ref="el => setChartRef(el, index)" :id="'weekReportEchart' + index" style="height:100%;"></div> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<script setup> |
||||||
|
import dayjs from 'dayjs' |
||||||
|
import { ref, reactive, onMounted } from 'vue' |
||||||
|
import * as echarts from "echarts"; |
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance() |
||||||
|
const alignment = 'center' |
||||||
|
const start = ref(dayjs().subtract(6, 'day').format('YYYY-MM-DD')) |
||||||
|
const end = ref(dayjs().format('YYYY-MM-DD')) |
||||||
|
const queryParams = reactive({ |
||||||
|
dateTime: [start.value, end.value] |
||||||
|
}) |
||||||
|
|
||||||
|
// 存储图表实例的数组 |
||||||
|
const chartInstances = ref([]) |
||||||
|
|
||||||
|
// 设置图表引用 |
||||||
|
const setChartRef = (el, index) => { |
||||||
|
if (el) { |
||||||
|
chartInstances.value[index] = el; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
let weekReportData = ref([ |
||||||
|
{ |
||||||
|
title: "雨情", |
||||||
|
unit: "mm/h", |
||||||
|
textTitle: "雨情测报各站点降雨变化趋势图", |
||||||
|
stationType: "A", |
||||||
|
isEcharts: true, |
||||||
|
totalRain: "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: "水情", |
||||||
|
unit: "m", |
||||||
|
textTitle: "水位变化趋势图", |
||||||
|
stationType: "B", |
||||||
|
isEcharts: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: "温度", |
||||||
|
unit: "℃", |
||||||
|
textTitle: "温度变化趋势图", |
||||||
|
stationType: "T", |
||||||
|
isEcharts: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: "风速", |
||||||
|
unit: "m/s", |
||||||
|
textTitle: "风速变化趋势图", |
||||||
|
stationType: "S", |
||||||
|
isEcharts: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: "湿度", |
||||||
|
unit: "%", |
||||||
|
textTitle: "湿度变化趋势图", |
||||||
|
stationType: "R", |
||||||
|
isEcharts: true, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: "风向", |
||||||
|
unit: "", |
||||||
|
textTitle: "", |
||||||
|
stationType: "U", |
||||||
|
isEcharts: false, |
||||||
|
} |
||||||
|
]) |
||||||
|
const loading = ref(false) |
||||||
|
const rainTableData = ref([]) |
||||||
|
const getList = async () => { |
||||||
|
let params = { |
||||||
|
startDate: queryParams.dateTime[0], |
||||||
|
endDate: queryParams.dateTime[1] |
||||||
|
} |
||||||
|
loading.value = true; |
||||||
|
try { |
||||||
|
const res = await proxy.axiosPost2('/data/statistics/getWeekReport', params) |
||||||
|
if (res.code == 0) { |
||||||
|
let obj = res.data |
||||||
|
weekReportData.value.forEach((item, index) => { |
||||||
|
switch (item.stationType) { |
||||||
|
case 'A': |
||||||
|
let list = [ |
||||||
|
{ |
||||||
|
yujingzhi: "预警值", |
||||||
|
name: "三级预警", |
||||||
|
oneHourValue: "20", |
||||||
|
threeHourValue: "30", |
||||||
|
sessionValue: "50", |
||||||
|
}, |
||||||
|
{ |
||||||
|
yujingzhi: "预警值", |
||||||
|
name: "二级预警", |
||||||
|
oneHourValue: "30", |
||||||
|
threeHourValue: "50", |
||||||
|
sessionValue: "80", |
||||||
|
}, |
||||||
|
{ |
||||||
|
yujingzhi: "预警值", |
||||||
|
name: "一级预警", |
||||||
|
oneHourValue: "40", |
||||||
|
threeHourValue: "100", |
||||||
|
sessionValue: "120", |
||||||
|
} |
||||||
|
] |
||||||
|
item.tableData = obj.rainTableData.concat(list) |
||||||
|
item.xAxisData = obj.rainChartXdata |
||||||
|
item.seriesData = obj.rainChartData |
||||||
|
item.legendData = obj.rainChartData.map(seriesItem => seriesItem.name) |
||||||
|
item.totalRain = obj.totalRain |
||||||
|
break; |
||||||
|
case 'B': |
||||||
|
case 'C': |
||||||
|
item.tableData = obj.waterTableData |
||||||
|
item.xAxisData = obj.waterChartXdata |
||||||
|
item.seriesData = obj.waterChartData |
||||||
|
item.legendData = obj.waterChartData.map(seriesItem => seriesItem.name) |
||||||
|
break; |
||||||
|
case 'T': |
||||||
|
item.tempAvg = obj.tempAvg |
||||||
|
item.tempMax = obj.tempMax |
||||||
|
item.tableData = obj.tempTableData |
||||||
|
item.xAxisData = obj.tempChartXdata |
||||||
|
item.seriesData = obj.tempChartData |
||||||
|
item.legendData = obj.tempChartData.map(seriesItem => seriesItem.name) |
||||||
|
break; |
||||||
|
case 'S': |
||||||
|
item.tableData = obj.wsTableData |
||||||
|
item.xAxisData = obj.qxChartXdata |
||||||
|
item.seriesData = obj.wsChartData |
||||||
|
item.legendData = obj.wsChartData.map(seriesItem => seriesItem.name) |
||||||
|
break; |
||||||
|
case 'R': |
||||||
|
item.tableData = obj.rhTableData |
||||||
|
item.xAxisData = obj.qxChartXdata |
||||||
|
item.seriesData = obj.rhChartData |
||||||
|
item.legendData = obj.rhChartData.map(seriesItem => seriesItem.name) |
||||||
|
break; |
||||||
|
case 'U': |
||||||
|
item.tableData = obj.wdrTableData |
||||||
|
item.TableHeader = obj.wdrTableHeader |
||||||
|
break; |
||||||
|
} |
||||||
|
// 只为需要图表的项初始化图表 |
||||||
|
if (item.isEcharts && chartInstances.value[index]) { |
||||||
|
nextTick(() => { |
||||||
|
initEchart(item, index) |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
console.error(error) |
||||||
|
} finally { |
||||||
|
loading.value = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const initEchart = (item, index) => { |
||||||
|
// 确保图表容器存在 |
||||||
|
if (!chartInstances.value[index]) { |
||||||
|
console.warn(`图表容器不存在: index ${index}`) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// 销毁已存在的图表实例 |
||||||
|
if (chartInstances.value[index].chartInstance) { |
||||||
|
chartInstances.value[index].chartInstance.dispose() |
||||||
|
} |
||||||
|
|
||||||
|
let myEcharts = echarts.init(chartInstances.value[index]); |
||||||
|
// 将图表实例保存到容器元素上 |
||||||
|
chartInstances.value[index].chartInstance = myEcharts |
||||||
|
|
||||||
|
const series = item.seriesData.map((seriesItem, seriesIndex) => { |
||||||
|
const colors = [ |
||||||
|
["#1075fd", "#164fb4"], |
||||||
|
["#0fec7d", "#2fbb18"], |
||||||
|
["#d364fd", "#a700bf"], |
||||||
|
["#5cffea", "#1aa2c2"], |
||||||
|
["#f2b622", "#c54b17"], |
||||||
|
["#fc3c54", "#d70005"], |
||||||
|
["#EE1289", "#8B0A50"], |
||||||
|
["#ee9c9c", "#755252"], |
||||||
|
["#06e8d6", "#078075"], |
||||||
|
["#de79c2", "#cd5c5c"], |
||||||
|
["#bebe0f", "#8B8B00"], |
||||||
|
["#00F5FF", "#6b8e23"], |
||||||
|
["#f50000", "#590404"], |
||||||
|
["#00CD66", "#3cb371"], |
||||||
|
["#c400fa", "#48005d"], |
||||||
|
["#eca86c", "#5e4310"], |
||||||
|
]; |
||||||
|
const color = colors[seriesIndex % colors.length]; |
||||||
|
|
||||||
|
return { |
||||||
|
name: seriesItem.name, // 使用seriesItem.name而不是item.legendData[seriesIndex] |
||||||
|
type: 'line', |
||||||
|
showSymbol: false, |
||||||
|
// barWidth: "20", // 线图不需要barWidth |
||||||
|
itemStyle: { |
||||||
|
normal: { |
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ |
||||||
|
{ offset: 0, color: color[0] }, |
||||||
|
{ offset: 1, color: color[1] } |
||||||
|
]), |
||||||
|
}, |
||||||
|
}, |
||||||
|
data: seriesItem.data, |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
let option = { |
||||||
|
title: { |
||||||
|
text: item.textTitle, |
||||||
|
subtext: '', |
||||||
|
x: 'center', |
||||||
|
textStyle: { |
||||||
|
fontSize: 16, |
||||||
|
color: "#000", |
||||||
|
}, |
||||||
|
// top: "8%", |
||||||
|
// left: "30%", |
||||||
|
}, |
||||||
|
tooltip: { |
||||||
|
trigger: "axis", |
||||||
|
axisPointer: { |
||||||
|
// 坐标轴指示器,坐标轴触发有效 |
||||||
|
type: "shadow", // 默认为直线,可选为:'line' | 'shadow' |
||||||
|
}, |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: '15px', |
||||||
|
right: '15px', |
||||||
|
bottom: '10px', |
||||||
|
top: '50px', |
||||||
|
containLabel: true |
||||||
|
}, |
||||||
|
legend: { |
||||||
|
data: item.legendData || [], |
||||||
|
// right: 10, |
||||||
|
top: 24, |
||||||
|
textStyle: { |
||||||
|
color: "#000", |
||||||
|
}, |
||||||
|
// itemWidth: 12, |
||||||
|
// itemHeight: 10, |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
boundaryGap: true, |
||||||
|
data: item.xAxisData || [], |
||||||
|
axisLabel: { |
||||||
|
textStyle: { |
||||||
|
color: "#000", |
||||||
|
}, |
||||||
|
formatter: function (value) { |
||||||
|
return dayjs(value).format('MM/DD H时'); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: `${item.title}(${item.unit})`, |
||||||
|
nameLocation: 'end', |
||||||
|
nameTextStyle: { |
||||||
|
color: '#464b50' |
||||||
|
}, |
||||||
|
nameGap: 15, |
||||||
|
axisLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#ccc", |
||||||
|
}, |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: true, |
||||||
|
lineStyle: { |
||||||
|
color: "#ccc", |
||||||
|
}, |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
textStyle: { |
||||||
|
color: "#000000", |
||||||
|
}, |
||||||
|
formatter: function (value) { |
||||||
|
return value.toFixed(2); |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
series: series, |
||||||
|
}; |
||||||
|
|
||||||
|
myEcharts.setOption(option); |
||||||
|
|
||||||
|
// 确保图表尺寸适应容器 |
||||||
|
const resizeChart = () => { |
||||||
|
if (myEcharts) { |
||||||
|
myEcharts.resize({ |
||||||
|
width: chartInstances.value[index].clientWidth, |
||||||
|
height: chartInstances.value[index].clientHeight |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// 初始化时调整一次大小 |
||||||
|
setTimeout(resizeChart, 100); |
||||||
|
} |
||||||
|
|
||||||
|
const handleQuery = () => { |
||||||
|
getList() |
||||||
|
} |
||||||
|
|
||||||
|
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => { |
||||||
|
// 获取实际数据行数(不包括最后三行预警数据) |
||||||
|
const dataRows = weekReportData.value[0].tableData ? weekReportData.value[0].tableData.slice(0, -3).length : 0; |
||||||
|
console.log(dataRows, 'dataRows') |
||||||
|
// 前dataRows行的合并规则 |
||||||
|
if (rowIndex < dataRows) { |
||||||
|
// 第一列不合并 |
||||||
|
if (columnIndex === 0) { |
||||||
|
return [0, 0]; |
||||||
|
} else if (columnIndex === 1) { |
||||||
|
return [1, 2] |
||||||
|
} |
||||||
|
return [1, 1]; |
||||||
|
} |
||||||
|
|
||||||
|
// 最后三行(预警值行)的合并规则 |
||||||
|
if (rowIndex >= dataRows && rowIndex < dataRows + 3) { |
||||||
|
if (columnIndex === 0) { |
||||||
|
if (rowIndex === dataRows) { |
||||||
|
// 第一行合并三行 |
||||||
|
return [3, 1]; |
||||||
|
} else { |
||||||
|
// 其他两行隐藏 |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
} |
||||||
|
if ([2, 4].includes(columnIndex)) { |
||||||
|
return [1, 2]; |
||||||
|
} if ([3, 5].includes(columnIndex)) { |
||||||
|
return [0, 0]; |
||||||
|
} |
||||||
|
return [1, 1] |
||||||
|
} |
||||||
|
|
||||||
|
return [1, 1]; |
||||||
|
}; |
||||||
|
onMounted(() => { |
||||||
|
getList() |
||||||
|
}) |
||||||
|
</script> |
||||||
|
<style scoped lang="scss"> |
||||||
|
.text-center { |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
.report-rain-table th, |
||||||
|
.report-rain-table td { |
||||||
|
padding: 8px 0; |
||||||
|
} |
||||||
|
|
||||||
|
:deep(.double-header-table .el-table__header tr:nth-child(2)) { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
</style> |
||||||
Loading…
Reference in new issue