forked from integrated_whb/integrated_whb_vue
453 lines
11 KiB
Vue
453 lines
11 KiB
Vue
<template>
|
||
<div class="p-20">
|
||
<el-row>
|
||
<el-col :span="24">
|
||
<el-card body-class="p-0">
|
||
<div class="tabs">
|
||
<div
|
||
v-for="(item, index) in tabsList"
|
||
:key="item.label"
|
||
:class="['tab', { active: tabIndex === index + 1 }]"
|
||
@click="fnTabsChange(item.type)"
|
||
>
|
||
{{ item.label }}
|
||
</div>
|
||
</div>
|
||
<el-form
|
||
:model="searchForm"
|
||
style="flex: 1"
|
||
class="ml-20"
|
||
@submit.prevent="fnGetData"
|
||
>
|
||
<el-row>
|
||
<el-col :span="4">
|
||
<el-form-item v-if="tabIndex === 1" prop="time">
|
||
<el-date-picker
|
||
v-model="searchForm.time"
|
||
type="date"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item v-if="tabIndex === 2" prop="time">
|
||
<el-date-picker
|
||
v-model="searchForm.time"
|
||
type="week"
|
||
format="YYYY 第ww周"
|
||
value-format="YYYY-MM-DD"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item v-if="tabIndex === 3" prop="time">
|
||
<el-date-picker
|
||
v-model="searchForm.time"
|
||
type="month"
|
||
format="YYYY-MM"
|
||
value-format="YYYY-MM-DD"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="4">
|
||
<el-form-item label-width="10px">
|
||
<el-button type="primary" native-type="submit"
|
||
>搜索
|
||
</el-button>
|
||
<el-button native-type="reset" @click="fnGetData">
|
||
重置
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="24" class="mt-20">
|
||
<el-card>
|
||
<div class="main_title">聚集报警趋势</div>
|
||
<div id="main1"></div>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="24" class="mt-20">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-card>
|
||
<div class="main_title">聚集数据统计</div>
|
||
<el-scrollbar style="height: 220px">
|
||
<div class="aggregated_data_statistics">
|
||
<div
|
||
v-for="(item, index) in aggregatedDataStatistics"
|
||
:key="index"
|
||
class="item"
|
||
>
|
||
<div
|
||
class="title"
|
||
:style="{ 'background-color': item.color }"
|
||
>
|
||
{{ item.title }}
|
||
</div>
|
||
<div class="content">
|
||
<div class="value">报警数量:{{ item.num }}</div>
|
||
<el-progress
|
||
:percentage="
|
||
item.value !== 0 ? item.num / item.value : 0
|
||
"
|
||
:color="item.color"
|
||
/>
|
||
<div class="times">
|
||
<div
|
||
v-for="(item1, index1) in item.timeArr"
|
||
:key="index1"
|
||
class="time"
|
||
>
|
||
<div class="time_title">{{ item1.timeTitle }}:</div>
|
||
<div class="time_value">{{ item1.timeValue }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-scrollbar>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-card>
|
||
<div class="main_title">聚集区域统计</div>
|
||
<el-scrollbar style="height: 220px">
|
||
<div class="aggregated-area-statistics">
|
||
<div
|
||
v-for="(item, index) in aggregatedAreaStatistics"
|
||
:key="index"
|
||
class="item"
|
||
>
|
||
<div class="value">
|
||
<div class="title">{{ item.title }}</div>
|
||
<div class="num">报警数量:{{ item.num }}</div>
|
||
</div>
|
||
<div class="alarms">
|
||
<div
|
||
v-for="(item1, index1) in item.alarmArr"
|
||
:key="index1"
|
||
class="alarm"
|
||
>
|
||
<div
|
||
class="bg"
|
||
:style="{ 'background-color': item1.color }"
|
||
/>
|
||
<div class="alarm_title">{{ item1.alarmTitle }}</div>
|
||
<div class="alarm_value">{{ item1.alarmValue }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-scrollbar>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||
import dayjs from "dayjs";
|
||
import * as echarts from "echarts";
|
||
import {
|
||
getAggregatedDataStatistics,
|
||
getAggregationAlarmTrend,
|
||
getAggregationAreaStatistics,
|
||
} from "@/request/aggregation_management.js";
|
||
|
||
let myChart1;
|
||
const tabsList = [
|
||
{ label: "每日统计", type: 1 },
|
||
{ label: "每周统计", type: 2 },
|
||
{ label: "每月统计", type: 3 },
|
||
];
|
||
const tabIndex = ref(1);
|
||
const searchForm = ref({ time: dayjs().format("YYYY-MM-DD") });
|
||
const aggregatedDataStatistics = ref([]);
|
||
const aggregatedAreaStatistics = ref([]);
|
||
const fnTabsChange = (event) => {
|
||
if (event === 1) searchForm.value.time = dayjs().format("YYYY-MM-DD");
|
||
if (event === 2) searchForm.value.time = dayjs().format("YYYY-MM-DD");
|
||
if (event === 3)
|
||
searchForm.value.time = dayjs().startOf("month").format("YYYY-MM-DD");
|
||
tabIndex.value = event;
|
||
fnGetData();
|
||
};
|
||
const fnGetData = async () => {
|
||
const aggregationAlarmTrendData = await getAggregationAlarmTrend({
|
||
type: tabIndex.value,
|
||
time: searchForm.value.time,
|
||
});
|
||
myChart1 && myChart1.dispose();
|
||
fnInitEcharts(aggregationAlarmTrendData.data);
|
||
const aggregatedDataStatisticsData = await getAggregatedDataStatistics({
|
||
type: tabIndex.value,
|
||
time: searchForm.value.time,
|
||
});
|
||
const aggregatedAreaStatisticsData = await getAggregationAreaStatistics({
|
||
type: tabIndex.value,
|
||
time: searchForm.value.time,
|
||
});
|
||
aggregatedDataStatistics.value = aggregatedDataStatisticsData.data;
|
||
aggregatedAreaStatistics.value = aggregatedAreaStatisticsData.data;
|
||
};
|
||
const fnInitEcharts = (data) => {
|
||
myChart1 = echarts.init(document.querySelector("#main1"));
|
||
const option = {
|
||
legend: {
|
||
data: ["一级聚集", "二级聚集", "三级聚集", "聚集总计"],
|
||
top: "0%",
|
||
textStyle: {
|
||
color: "#fff",
|
||
},
|
||
},
|
||
grid: {
|
||
left: "2%",
|
||
right: "2%",
|
||
bottom: "5%",
|
||
top: "13%",
|
||
containLabel: true,
|
||
},
|
||
tooltip: {
|
||
trigger: "axis",
|
||
},
|
||
xAxis: {
|
||
type: "category",
|
||
boundaryGap: false,
|
||
data: data.xdata,
|
||
axisLabel: {
|
||
color: "#fff",
|
||
},
|
||
axisLine: {
|
||
lineStyle: {
|
||
color: "#102b60",
|
||
},
|
||
},
|
||
},
|
||
yAxis: {
|
||
type: "value",
|
||
axisLabel: {
|
||
color: "#fff",
|
||
},
|
||
axisLine: {
|
||
lineStyle: {
|
||
color: "#102b60",
|
||
},
|
||
},
|
||
splitLine: {
|
||
lineStyle: {
|
||
color: "#102b60",
|
||
},
|
||
},
|
||
},
|
||
series: [
|
||
{
|
||
name: "一级聚集",
|
||
type: "line",
|
||
data: data.one,
|
||
itemStyle: {
|
||
normal: {
|
||
color: "red",
|
||
lineStyle: {
|
||
color: "red",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: "二级聚集",
|
||
type: "line",
|
||
data: data.two,
|
||
itemStyle: {
|
||
normal: {
|
||
color: "orange",
|
||
lineStyle: {
|
||
color: "orange",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: "三级聚集",
|
||
type: "line",
|
||
data: data.three,
|
||
itemStyle: {
|
||
normal: {
|
||
color: "#ffeb3b",
|
||
lineStyle: {
|
||
color: "#ffeb3b",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: "聚集总计",
|
||
type: "line",
|
||
data: data.zong,
|
||
itemStyle: {
|
||
normal: {
|
||
color: "#0385f4",
|
||
lineStyle: {
|
||
color: "#0385f4",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
],
|
||
};
|
||
myChart1.setOption(option);
|
||
};
|
||
onMounted(() => {
|
||
fnGetData();
|
||
window.onresize = function () {
|
||
myChart1 && myChart1.resize();
|
||
};
|
||
});
|
||
onBeforeUnmount(() => {
|
||
myChart1 = null;
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
:deep {
|
||
.el-card__body {
|
||
padding: 18px !important;
|
||
}
|
||
|
||
.p-0 {
|
||
padding: 0 !important;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.el-form-item {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
|
||
.tab {
|
||
padding: 20px;
|
||
cursor: pointer;
|
||
|
||
&:hover,
|
||
&.active {
|
||
background-color: var(--el-fill-color-light);
|
||
color: var(--el-color-check);
|
||
}
|
||
}
|
||
}
|
||
|
||
.main_title {
|
||
padding: 0 18px 18px 18px;
|
||
border-bottom: 1px solid var(--el-card-border-color);
|
||
margin: 0 -18px;
|
||
}
|
||
|
||
#main1 {
|
||
width: 100%;
|
||
height: 300px;
|
||
}
|
||
|
||
.el-card {
|
||
margin: 0;
|
||
}
|
||
|
||
.aggregated_data_statistics {
|
||
font-size: 12px;
|
||
|
||
.item {
|
||
margin-top: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.title {
|
||
width: max-content;
|
||
padding: 5px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.content {
|
||
margin-left: 10px;
|
||
flex: 1;
|
||
|
||
.value {
|
||
text-align: right;
|
||
padding-right: 50px;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.times {
|
||
margin-top: 5px;
|
||
display: flex;
|
||
|
||
.time {
|
||
display: flex;
|
||
margin-right: 10px;
|
||
background-color: #b0b0b0;
|
||
border-radius: 4px;
|
||
padding: 5px;
|
||
|
||
.time_value {
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.aggregated-area-statistics {
|
||
font-size: 12px;
|
||
|
||
.item {
|
||
margin-top: 10px;
|
||
background-color: var(--el-fill-color-light);
|
||
padding: 10px;
|
||
border-radius: 4px;
|
||
|
||
.value {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.title {
|
||
margin-right: 10px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.num {
|
||
font-weight: bold;
|
||
}
|
||
}
|
||
|
||
.alarms {
|
||
display: flex;
|
||
|
||
.alarm {
|
||
margin-top: 10px;
|
||
margin-right: 10px;
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: #b0b0b0;
|
||
border-radius: 4px;
|
||
padding: 5px;
|
||
|
||
.bg {
|
||
width: 10px;
|
||
height: 10px;
|
||
margin-right: 5px;
|
||
}
|
||
|
||
.alarm_title {
|
||
margin-right: 10px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|