聚集告警记录、聚集概览

pull/1/head
LiuJiaNan 2024-02-26 11:27:02 +08:00
parent 47dd8dffb6
commit 2f7623585f
5 changed files with 530 additions and 3 deletions

View File

@ -0,0 +1,10 @@
import { post } from "@/request/axios.js";
export const getGatheringAlarmRecordsList = (params) =>
post("/positAlarm/getAlarmRecordList", params); // 聚集告警记录列表
export const getAggregationAlarmTrend = (params) =>
post("/positAlarm/aggregateAlarmTrends", params); // 聚集报警趋势
export const getAggregatedDataStatistics = (params) =>
post("/positAlarm/aggregateDataStatistics", params); // 聚集区域统计
export const getAggregationAreaStatistics = (params) =>
post("/positAlarm/aggregateDataStatisticsByGroup", params); // 聚集数据统计

View File

@ -25,8 +25,7 @@ export const setAssignmentTicketAreaSettingsDelete = (params) =>
post("/positAlarm/otherRegion/regionDelete", params); // 作业票区域设置删除 post("/positAlarm/otherRegion/regionDelete", params); // 作业票区域设置删除
export const setPosition = (params) => export const setPosition = (params) =>
post("/positAlarm/otherRegion/redrawTheArea", params); // 区域选点 post("/positAlarm/otherRegion/redrawTheArea", params); // 区域选点
// TODO 接口不对
export const getPathPlanningList = (params) => export const getPathPlanningList = (params) =>
post("/positAlarm/coordinateLine/addCoordinateLine", params); // 路径规划列表 post("/positAlarm/coordinateLine/tree", params); // 路径规划列表
export const setPathPlanningDelete = (params) => export const setPathPlanningDelete = (params) =>
post("/positAlarm/coordinateLine/batchDelete", params); // 路径规划删除 post("/positAlarm/coordinateLine/batchDelete", params); // 路径规划删除

View File

@ -0,0 +1,63 @@
<template>
<div>
<el-card>
<el-form
:model="searchForm"
label-width="60px"
@submit.prevent="fnResetPagination"
>
<el-row>
<el-col :span="6">
<el-form-item label="关键字" prop="str">
<el-input v-model="searchForm.str" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label-width="30px">
<el-button type="primary" native-type="submit">搜索</el-button>
<el-button native-type="reset" @click="fnResetPagination">
重置
</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<layout-card>
<layout-table
v-model:pagination="pagination"
:data="list"
@get-data="fnGetData"
>
<el-table-column label="序号" width="70">
<template #default="{ $index }">
{{ serialNumber(pagination, $index) }}
</template>
</el-table-column>
<el-table-column label="聚集地点" prop="regName" />
<el-table-column label="开始时间" prop="regName" />
<el-table-column label="结束时间" prop="regName" />
<el-table-column label="状态" prop="regName" />
<el-table-column label="操作" width="200">
<template #default="{ row }">
{{ row }}
</template>
</el-table-column>
</layout-table>
</layout-card>
</div>
</template>
<script setup>
import useListData from "@/assets/js/useListData.js";
import { serialNumber } from "@/assets/js/utils.js";
import { getGatheringAlarmRecordsList } from "@/request/aggregation_management.js";
const { list, searchForm, pagination, fnGetData, fnResetPagination } =
useListData(getGatheringAlarmRecordsList, {
otherParams: { status: "" },
key: "rows",
});
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,452 @@
<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>

View File

@ -86,7 +86,10 @@ import { reactive } from "vue";
import Add from "./components/add.vue"; import Add from "./components/add.vue";
const { list, searchForm, tableRef, pagination, fnGetData, fnResetPagination } = const { list, searchForm, tableRef, pagination, fnGetData, fnResetPagination } =
useListData(getPathPlanningList); useListData(getPathPlanningList, {
defaultSearchForm: { str: "" },
key: "rows",
});
const data = reactive({ const data = reactive({
addDialogVisible: false, addDialogVisible: false,
}); });