告警管理页面删除仪表盘,添加弹窗布局动态处理,添加弹窗点击事件

This commit is contained in:
龚皓 2024-10-16 14:53:41 +08:00
parent 1b6a66302f
commit 689a167f4e
1 changed files with 87 additions and 14 deletions

View File

@ -1,23 +1,22 @@
<template> <template>
<div class="alert-container"> <div class="alert-container">
<el-row class="top-pan"> <!-- <el-row class="top-pan">
<el-col :sm="24" :md="12" class="panel-section"> <el-col :sm="24" :md="12" class="panel-section">
<statistics /> <statistics />
</el-col> </el-col>
<el-col :sm="24" :md="12" class="panel-section"> <el-col :sm="24" :md="12" class="panel-section">
<alertChart /> <alertChart />
</el-col> </el-col>
</el-row> </el-row> -->
<el-row class="middle-row"> <el-row class="middle-row">
<span> <span>
告警总数:{{ totalItems }} 告警总数:{{ displayTotalItems }}
</span> </span>
</el-row> </el-row>
<el-row class="table-row"> <el-row class="table-row">
<el-col :span="24"> <el-col :span="24">
<div class="table-container"> <div class="table-container">
<el-table :data="tableData" style="width:100%; height: 100%;" header-row-class-name="table-header" <el-table :data="tableData" style="width:100%; height: 100%;" header-row-class-name="table-header" :fit="true">
:fit="true">
<el-table-column prop="id" label="告警编号" min-width="100"></el-table-column> <el-table-column prop="id" label="告警编号" min-width="100"></el-table-column>
<el-table-column label="告警类型" min-width="150"> <el-table-column label="告警类型" min-width="150">
<template v-slot="scope"> <template v-slot="scope">
@ -82,7 +81,7 @@
<p>备注: {{ selectedRow.note }}</p> <p>备注: {{ selectedRow.note }}</p>
</el-col> </el-col>
</el-row> </el-row>
<div class="event-media"> <!-- <div class="event-media">
<div v-for="medium in selectedRow.mediums" :key="medium.id" class="media-container"> <div v-for="medium in selectedRow.mediums" :key="medium.id" class="media-container">
<div v-if="medium.name === 'video'" class="media-item video-item"> <div v-if="medium.name === 'video'" class="media-item video-item">
<p>告警关联视频</p> <p>告警关联视频</p>
@ -93,19 +92,40 @@
<el-image :src="medium.file" fit="contain"></el-image> <el-image :src="medium.file" fit="contain"></el-image>
</div> </div>
</div> </div>
</div> -->
<div class="event-media" :class="{ 'center-media' :mediums.length === 1 }">
<!-- 告警关联视频 -->
<div v-if="hasVideo" class="media-container video-item">
<p>告警关联视频</p>
<video :src="videoFile" controls @click="openMediaDialog('video', videoFile)"></video>
</div>
<!-- 告警关联图片 -->
<div v-if="hasSnapshot" class="media-container image-item">
<p>告警关联图片</p>
<el-image :src="snapshotFile" fit="contain" @click="openMediaDialog('image', snapshotFile)"></el-image>
</div>
</div> </div>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<div class=""></div> <div class=""></div>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog v-model="mediaDialogVisible" width="70%">
<div v-if="mediaType === 'image'">
<el-image :src="mediaSrc" fit="contain" style="width: 100%;"></el-image>
</div>
<div v-if="mediaType === 'video'">
<video :src="mediaSrc" controls style="width: 100%;"></video>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted, computed } from 'vue';
import Statistics from '@/components/Statistics.vue'; // import Statistics from '@/components/Statistics.vue';
import AlertChart from '@/components/AlertChart.vue'; // import AlertChart from '@/components/AlertChart.vue';
import { BoxApi } from '@/utils/boxApi.ts'; // BoxApi import { BoxApi } from '@/utils/boxApi.ts'; // BoxApi
// BoxApi // BoxApi
@ -114,6 +134,10 @@ const boxApi = new BoxApi();
// //
const tableData = ref([]); const tableData = ref([]);
const dialogVisible = ref(false); const dialogVisible = ref(false);
const mediaDialogVisible = ref(false);
const mediaType = ref('');
const mediaSrc = ref('');
const selectedRow = ref({}); const selectedRow = ref({});
const mediums = ref([]); const mediums = ref([]);
const duration = ref(''); const duration = ref('');
@ -124,8 +148,31 @@ const statusMapping = {
}; };
const currentPage = ref(1); const currentPage = ref(1);
const pageSize = ref(20); const pageSize = ref(20);
const totalItems = ref(0);
const token = ref(null); const token = ref(null);
const totalItems = ref(0);
const displayTotalItems = ref(0); //
const openMediaDialog = (type, src) => {
mediaType.value = type; //
mediaSrc.value = src; //
mediaDialogVisible.value = true; //
};
// mediums
const hasVideo = computed(() => mediums.value.some(medium => medium.name === 'video'));
const hasSnapshot = computed(() => mediums.value.some(medium => medium.name === 'snapshot'));
//
const videoFile = computed(() => {
const video = mediums.value.find(medium => medium.name === 'video');
return video ? video.file : '';
});
const snapshotFile = computed(() => {
const snapshot = mediums.value.find(medium => medium.name === 'snapshot');
return snapshot ? snapshot.file : '';
});
// //
const fetchTypeMapping = async (token) => { const fetchTypeMapping = async (token) => {
@ -146,11 +193,32 @@ const fetchEvents = async () => {
const { tableData: data, totalItems: total } = await boxApi.getEvents(token.value, pageSize.value, currentPage.value); // 使 BoxApi getEvents const { tableData: data, totalItems: total } = await boxApi.getEvents(token.value, pageSize.value, currentPage.value); // 使 BoxApi getEvents
tableData.value = data; tableData.value = data;
totalItems.value = total; totalItems.value = total;
animateNumberChange(total);
} catch (error) { } catch (error) {
console.error("Error fetching events data:", error); console.error("Error fetching events data:", error);
} }
}; };
const animateNumberChange = (newTotal) => {
const stepTime = 50; //
// const stepCount = Math.abs(newTotal - displayTotalItems.value);
const stepCount = Math.abs(newTotal - displayTotalItems.value) / 20;
const incrementStep = Math.ceil((newTotal - displayTotalItems.value) / stepCount); //
const step = () => {
if (displayTotalItems.value < newTotal) {
displayTotalItems.value = Math.min(displayTotalItems.value + incrementStep, newTotal);
requestAnimationFrame(step);
} else if (displayTotalItems.value > newTotal) {
displayTotalItems.value = Math.max(displayTotalItems.value - incrementStep, newTotal);
requestAnimationFrame(step);
}
};
step();
};
// //
const handleView = (row) => { const handleView = (row) => {
selectedRow.value = row; selectedRow.value = row;
@ -209,7 +277,7 @@ onMounted(async () => {
background-color: #f5f7fa; background-color: #f5f7fa;
} }
.top-pan { /* .top-pan {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
display: flex; display: flex;
@ -223,7 +291,7 @@ onMounted(async () => {
background-color: #fff; background-color: #fff;
box-shadow: 0 20px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 20px 8px rgba(0, 0, 0, 0.1);
border-radius: 15px; border-radius: 15px;
} } */
.middle-row { .middle-row {
min-height: 5vw; min-height: 5vw;
@ -233,12 +301,12 @@ onMounted(async () => {
font-size: 30px; font-size: 30px;
font-weight: bold; font-weight: bold;
background: linear-gradient(to bottom left, rgb(150, 151, 243), rgb(215, 214, 250)); background: linear-gradient(to bottom left, rgb(150, 151, 243), rgb(215, 214, 250));
border-radius: 8px; /* border-radius: 8px; */
} }
.table-container { .table-container {
width: 100%; width: 100%;
height: 380px; height: 620px;
min-height: 60%; min-height: 60%;
overflow-x: auto; overflow-x: auto;
} }
@ -257,6 +325,11 @@ onMounted(async () => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
width: 100%;
}
.center-media {
justify-content: center;
} }
.media-container { .media-container {