|
|
|
<!-- 监测数据 -->
|
|
|
|
<template>
|
|
|
|
<div class="data-statistics">
|
|
|
|
<div class="search-box">
|
|
|
|
<div class="options-box">
|
|
|
|
<el-cascader
|
|
|
|
size="small"
|
|
|
|
v-model="cascaderArr"
|
|
|
|
:options="cascaderOptions"
|
|
|
|
:props="cascaderProps"
|
|
|
|
@change="handleChangeCascader"
|
|
|
|
></el-cascader>
|
|
|
|
<el-date-picker
|
|
|
|
class="ml-12"
|
|
|
|
size="small"
|
|
|
|
v-model="dateArr"
|
|
|
|
type="daterange"
|
|
|
|
range-separator="至"
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
start-placeholder="开始日期"
|
|
|
|
end-placeholder="结束日期"
|
|
|
|
>
|
|
|
|
</el-date-picker>
|
|
|
|
<el-button type="primary" class="!ml-12" @click="handleSearch">查询</el-button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<el-radio-group v-model="showType" @change="handleChangeShowType">
|
|
|
|
<el-radio-button label="1">指标</el-radio-button>
|
|
|
|
<el-radio-button label="2">图表</el-radio-button>
|
|
|
|
</el-radio-group>
|
|
|
|
</div>
|
|
|
|
<div class="mt-24 statistics-main">
|
|
|
|
<!-- 指标 -->
|
|
|
|
<div v-if="showType === '1'">
|
|
|
|
<div class="attributes-box" v-for="(item, index) in attributesList" :key="index">
|
|
|
|
<div class="title">{{ item.group }}</div>
|
|
|
|
<div class="list-box">
|
|
|
|
<div class="list-item" v-for="(item2, index2) in item.items" :key="index2">
|
|
|
|
<div class="item-title">{{ item2.zhName }}({{ item2.unit }})</div>
|
|
|
|
<div class="item-value">
|
|
|
|
{{ item2.value == null ? "-" : item2.value }}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-if="!attributesList || !attributesList.length" class="pt-30 text-center">-暂无指标数据-</div>
|
|
|
|
</div>
|
|
|
|
<!-- 图表 -->
|
|
|
|
<div v-else-if="showType === '2'" class="echarts-box">
|
|
|
|
<div class="echarts-dom-box">
|
|
|
|
<div class="title">水雨情监测</div>
|
|
|
|
<div ref="echartsRef1" class="echarts-dom"></div>
|
|
|
|
</div>
|
|
|
|
<div class="echarts-dom-box">
|
|
|
|
<div class="title">渗流监测</div>
|
|
|
|
<div ref="echartsRef2" class="echarts-dom"></div>
|
|
|
|
</div>
|
|
|
|
<div class="echarts-dom-box">
|
|
|
|
<div class="title">堤围工程堤段表面变形信息统计</div>
|
|
|
|
<div ref="echartsRef3" class="echarts-dom"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { onMounted, ref } from "vue";
|
|
|
|
import {
|
|
|
|
getReservoirCZListData,
|
|
|
|
getReservoirCDListData,
|
|
|
|
getReservoirMonitorIndexData,
|
|
|
|
getReservoirCZMonitorEchartsData,
|
|
|
|
} from "@/api/reservoir";
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
const props = defineProps({
|
|
|
|
resCode: {
|
|
|
|
type: String,
|
|
|
|
default: "",
|
|
|
|
},
|
|
|
|
});
|
|
|
|
const cascaderOptions: any = ref([]);
|
|
|
|
const showType: any = ref("1");
|
|
|
|
const cascaderArr: any = ref([]);
|
|
|
|
const dateArr: any = ref([]);
|
|
|
|
const cascaderProps: any = {
|
|
|
|
expandTrigger: "hover",
|
|
|
|
label: "stnm",
|
|
|
|
value: "stcd",
|
|
|
|
children: "children",
|
|
|
|
checkStrictly: true,
|
|
|
|
lazy: true,
|
|
|
|
lazyLoad(node: any, resolve: any) {
|
|
|
|
console.log("lazyLoad-node >>>>> ", node);
|
|
|
|
if (node && node.data && node.data.prjcd) {
|
|
|
|
getReservoirCDListData({
|
|
|
|
stcd: node.data.prjcd,
|
|
|
|
}).then((res) => {
|
|
|
|
resolve(res.records);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
resolve([]);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const attributesList: any = ref([]);
|
|
|
|
let echart1: any = null;
|
|
|
|
let echart2: any = null;
|
|
|
|
let echart3: any = null;
|
|
|
|
const echartsRef1 = ref();
|
|
|
|
const echartsRef2 = ref();
|
|
|
|
const echartsRef3 = ref();
|
|
|
|
|
|
|
|
function getData() {
|
|
|
|
switch (showType.value) {
|
|
|
|
case "1":
|
|
|
|
// 处理获取指标数据
|
|
|
|
getReservoirMonitorIndexData({
|
|
|
|
startTime: dateArr.value?.length ? dateArr.value[0] + " 00:00:00" : "",
|
|
|
|
endTime: dateArr.value?.length ? dateArr.value[1] + " 23:59:59" : "",
|
|
|
|
group: "DF",
|
|
|
|
resCode: props.resCode,
|
|
|
|
stcd: cascaderArr.value[0] || "",
|
|
|
|
mpcd: cascaderArr.value[1] || "",
|
|
|
|
}).then((res) => {
|
|
|
|
attributesList.value = res;
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case "2":
|
|
|
|
// 处理图表数据
|
|
|
|
getEchartsData();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function initChart(data: any, chartInstance: any, echartRes: any) {
|
|
|
|
// 渲染echarts
|
|
|
|
if (!echartRes) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (chartInstance) {
|
|
|
|
chartInstance.dispose();
|
|
|
|
}
|
|
|
|
let options = initLineOptions(data);
|
|
|
|
chartInstance = echarts.init(echartRes);
|
|
|
|
options && chartInstance.setOption(options);
|
|
|
|
}
|
|
|
|
// 折线图
|
|
|
|
function initLineOptions(data: any) {
|
|
|
|
const { markLine, xaxis, yaxis } = data;
|
|
|
|
if (!xaxis || !yaxis || !yaxis.length) return {};
|
|
|
|
let yAxis = yaxis.map((v: any) => {
|
|
|
|
return {
|
|
|
|
type: "value",
|
|
|
|
name: `${v.name}(${v.unit})`,
|
|
|
|
nameLocation: "end",
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
let series: any = [];
|
|
|
|
yaxis.forEach((v: any, i: any) => {
|
|
|
|
if (v.series?.length) {
|
|
|
|
v.series.forEach((v2: any) => {
|
|
|
|
series.push({
|
|
|
|
type: "line",
|
|
|
|
smooth: true,
|
|
|
|
yAxisIndex: i,
|
|
|
|
name: v2.name,
|
|
|
|
data: v2.data,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (markLine && markLine.length && series.length) {
|
|
|
|
let seriesItem = series.find((v: any) => v.yAxisIndex === 1) || series[0];
|
|
|
|
let colors = ["#f8afaf", "#bae4dd"];
|
|
|
|
let markLineData = markLine.map((v: any, i: any) => {
|
|
|
|
return {
|
|
|
|
name: v.name,
|
|
|
|
yAxis: v.value,
|
|
|
|
label: {
|
|
|
|
color: colors[i] || "red",
|
|
|
|
},
|
|
|
|
lineStyle: {
|
|
|
|
color: colors[i] || "red",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|
|
|
|
seriesItem.markLine = {
|
|
|
|
symbol: "none",
|
|
|
|
label: {
|
|
|
|
show: true,
|
|
|
|
position: "insideEndTop",
|
|
|
|
formatter: "{b}",
|
|
|
|
},
|
|
|
|
lineStyle: {
|
|
|
|
width: 2,
|
|
|
|
type: "solid",
|
|
|
|
color: colors[0] || "red",
|
|
|
|
},
|
|
|
|
data: markLineData,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
title: {
|
|
|
|
// text: "统计",
|
|
|
|
},
|
|
|
|
legend: {
|
|
|
|
orient: "horizontal",
|
|
|
|
top: "2%",
|
|
|
|
},
|
|
|
|
grid: {
|
|
|
|
left: "5%",
|
|
|
|
right: "10%",
|
|
|
|
bottom: "10%",
|
|
|
|
top: "20%",
|
|
|
|
containLabel: true,
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
trigger: "axis",
|
|
|
|
axisPointer: {
|
|
|
|
type: "cross",
|
|
|
|
label: {
|
|
|
|
backgroundColor: "#283b56",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
xAxis: [
|
|
|
|
{
|
|
|
|
type: "category",
|
|
|
|
name: "时间",
|
|
|
|
position: "bottom",
|
|
|
|
axisLine: {
|
|
|
|
onZero: false,
|
|
|
|
show: true,
|
|
|
|
},
|
|
|
|
axisTick: {
|
|
|
|
alignWithLabel: true,
|
|
|
|
},
|
|
|
|
data: xaxis,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
yAxis: yAxis,
|
|
|
|
series: series,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
function getEchartsData() {
|
|
|
|
// 水雨情监测
|
|
|
|
getReservoirCZMonitorEchartsData({
|
|
|
|
startTime: dateArr.value?.length ? dateArr.value[0] + " 00:00:00" : "",
|
|
|
|
endTime: dateArr.value?.length ? dateArr.value[1] + " 23:59:59" : "",
|
|
|
|
resCode: props.resCode,
|
|
|
|
stcd: cascaderArr.value[0] || "",
|
|
|
|
mpcd: cascaderArr.value[1] || "",
|
|
|
|
elementType: "C_SEEPAGE_FLOW",
|
|
|
|
}).then((res) => {
|
|
|
|
if (res.data) {
|
|
|
|
initChart(res.data, echart1, echartsRef1.value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// 渗流监测
|
|
|
|
getReservoirCZMonitorEchartsData({
|
|
|
|
startTime: dateArr.value?.length ? dateArr.value[0] + " 00:00:00" : "",
|
|
|
|
endTime: dateArr.value?.length ? dateArr.value[1] + " 23:59:59" : "",
|
|
|
|
resCode: props.resCode,
|
|
|
|
stcd: cascaderArr.value[0] || "",
|
|
|
|
elementType: "C_DISPLACEMENT",
|
|
|
|
}).then((res) => {
|
|
|
|
if (res.data) {
|
|
|
|
initChart(res.data, echart2, echartsRef2.value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// 堤围工程堤段表面变形信息统计
|
|
|
|
getReservoirCZMonitorEchartsData({
|
|
|
|
startTime: dateArr.value?.length ? dateArr.value[0] + " 00:00:00" : "",
|
|
|
|
endTime: dateArr.value?.length ? dateArr.value[1] + " 23:59:59" : "",
|
|
|
|
resCode: props.resCode,
|
|
|
|
mpcd: cascaderArr.value[1] || "",
|
|
|
|
elementType: "DF_WATER_LEVEL",
|
|
|
|
}).then((res) => {
|
|
|
|
if (res.data) {
|
|
|
|
initChart(res.data, echart3, echartsRef3.value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function handleSearch() {
|
|
|
|
attributesList.value = [];
|
|
|
|
getData();
|
|
|
|
}
|
|
|
|
function handleChangeCascader() {}
|
|
|
|
function handleChangeShowType() {
|
|
|
|
getData();
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
getReservoirCZListData({
|
|
|
|
data: {
|
|
|
|
page: 1,
|
|
|
|
pageSize: 1000,
|
|
|
|
prjcd: props.resCode,
|
|
|
|
},
|
|
|
|
}).then((res) => {
|
|
|
|
cascaderOptions.value = res.records;
|
|
|
|
});
|
|
|
|
getData();
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.data-statistics {
|
|
|
|
height: 100%;
|
|
|
|
:deep(.sy-cascader) .sy-input__wrapper,
|
|
|
|
:deep(.sy-range-editor--small.sy-input__wrapper) {
|
|
|
|
height: 32px !important;
|
|
|
|
line-height: 32px !important;
|
|
|
|
}
|
|
|
|
:deep(.sy-range-editor--small) .sy-range-input {
|
|
|
|
color: rgba(0, 0, 0, 0.9) !important;
|
|
|
|
}
|
|
|
|
.search-box {
|
|
|
|
display: flex;
|
|
|
|
justify-content: space-between;
|
|
|
|
align-items: center;
|
|
|
|
padding: 0 12px;
|
|
|
|
.options-box {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
gap: 8px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.attributes-box {
|
|
|
|
margin-bottom: 16px;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
padding: 24px 12px;
|
|
|
|
.title {
|
|
|
|
padding-left: 10px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 500;
|
|
|
|
position: relative;
|
|
|
|
&::before {
|
|
|
|
content: " ";
|
|
|
|
width: 4px;
|
|
|
|
height: 4px;
|
|
|
|
background: #36b29e;
|
|
|
|
position: absolute;
|
|
|
|
left: 1px;
|
|
|
|
top: 50%;
|
|
|
|
margin-top: -2px;
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.list-box {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
|
|
.list-item {
|
|
|
|
width: 236px;
|
|
|
|
height: 102px;
|
|
|
|
border: 1px solid #36b29e;
|
|
|
|
border-radius: 10px;
|
|
|
|
position: relative;
|
|
|
|
padding: 16px 24px;
|
|
|
|
margin-right: 16px;
|
|
|
|
margin-bottom: 12px;
|
|
|
|
background: linear-gradient(180deg, #eafffc 0%, rgba(222, 255, 250, 0) 100%), #ffffff;
|
|
|
|
overflow: hidden;
|
|
|
|
&::after {
|
|
|
|
position: absolute;
|
|
|
|
content: "";
|
|
|
|
background: url("@/assets/img/icon-attr-bg.png") no-repeat center center;
|
|
|
|
width: 64px;
|
|
|
|
height: 64px;
|
|
|
|
right: -12px;
|
|
|
|
bottom: -12px;
|
|
|
|
}
|
|
|
|
.item-title {
|
|
|
|
font-size: 14px;
|
|
|
|
}
|
|
|
|
.item-value {
|
|
|
|
margin-top: 12px;
|
|
|
|
font-size: 32px;
|
|
|
|
color: #36b29e;
|
|
|
|
font-weight: 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.echarts-box {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
padding: 24px 12px;
|
|
|
|
.echarts-dom-box {
|
|
|
|
margin-bottom: 24px;
|
|
|
|
&:nth-child(2n) {
|
|
|
|
margin-left: 24px;
|
|
|
|
}
|
|
|
|
.title {
|
|
|
|
padding-left: 10px;
|
|
|
|
font-size: 14px;
|
|
|
|
font-weight: 500;
|
|
|
|
position: relative;
|
|
|
|
margin-bottom: 12px;
|
|
|
|
&::before {
|
|
|
|
content: " ";
|
|
|
|
width: 4px;
|
|
|
|
height: 4px;
|
|
|
|
background: #36b29e;
|
|
|
|
position: absolute;
|
|
|
|
left: 1px;
|
|
|
|
top: 50%;
|
|
|
|
margin-top: -2px;
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.echarts-dom {
|
|
|
|
width: 478px;
|
|
|
|
height: 260px;
|
|
|
|
border: 1px solid #f0f0f0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.statistics-main {
|
|
|
|
height: calc(100% - 64px);
|
|
|
|
overflow: auto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.text-center {
|
|
|
|
padding-top: 30px;
|
|
|
|
text-align: center;
|
|
|
|
color: rgba(0, 0, 0, 0.9);
|
|
|
|
}
|
|
|
|
</style>
|