告警管理页面删除仪表盘,添加弹窗布局动态处理,添加弹窗点击事件
This commit is contained in:
parent
1b6a66302f
commit
689a167f4e
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue