665 lines
17 KiB
Vue
665 lines
17 KiB
Vue
<template>
|
|
<div class="realTimeManage">
|
|
<div class="left">
|
|
<!-- 云平台 -->
|
|
<div class="cloud-platform-box layout">
|
|
<div id="platform-left">
|
|
<div class="left-right-btn-box layout">
|
|
<button id="gq_nocheck" class="common_size"></button>
|
|
<span class="btn-desc">光圈</span>
|
|
<button id="gq2_nocheck" class="common_size"></button>
|
|
</div>
|
|
</div>
|
|
<div id="platform-center">
|
|
<div id="center-btn-top-box" class="layout">
|
|
<div class="fx-btn-box layout">
|
|
<button id="left_nocheck" class="common_size"></button>
|
|
</div>
|
|
<div class="fx-btn-box layout">
|
|
<button id="top_nocheck" class="common_size"></button>
|
|
<button id="bottom_nocheck" class="common_size"></button>
|
|
</div>
|
|
<div class="fx-btn-box layout">
|
|
<button id="right_nocheck" class="common_size"></button>
|
|
</div>
|
|
</div>
|
|
<div id="center-btn-bottom-box" class="layout">
|
|
<button id="sx_nocheck" class="common_size"></button>
|
|
<span class="btn-desc2">缩放</span>
|
|
<button id="fd_nocheck" class="common_size"></button>
|
|
</div>
|
|
</div>
|
|
<div id="platform-right">
|
|
<div class="left-right-btn-box layout">
|
|
<button id="jj_nocheck" class="common_size"></button>
|
|
<span class="btn-desc">聚焦</span>
|
|
<button id="yj_nocheck" class="common_size"></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 球机树 -->
|
|
<div class="tree-box tree">
|
|
<el-input placeholder="请输入关键字" prefix-icon="el-icon-search" v-model="filterText" maxlength="30"
|
|
style="margin: 10px 0;"></el-input>
|
|
<el-tree :data="treeData" icon="el-icon-search" node-key="id" :default-expanded-keys="idArr"
|
|
@node-click="handleNodeClick" :render-content="renderContent" style="font-size: 15px;letter-spacing: 1px;"
|
|
ref="tree" :highlight-current="true" :filter-node-method="filterNode">
|
|
<!-- <span class="custom-tree-node" slot-scope="{ node }">
|
|
<i :class="node.level == 1 ? 'pro_icon' : node.level == 2 ? 'pro_icon' : 'pro_icon'"></i>
|
|
<span>{{ node.label }}</span>
|
|
</span> -->
|
|
</el-tree>
|
|
</div>
|
|
</div>
|
|
<!-- 视频 -->
|
|
<div class="center">
|
|
<div class="change-box layout">
|
|
<el-button type="primary" plain @click="changePlayVideo(1)">1</el-button>
|
|
<el-button type="primary" plain @click="changePlayVideo(4)">4</el-button>
|
|
</div>
|
|
<!-- 球机视频 -->
|
|
<div class="video-box layout">
|
|
<video v-if="boxNum == 1 || boxNum == 4" id="videoPlayer1" :class="classStyle" autoplay="autoplay" loop="loop"
|
|
muted controls="controls"></video>
|
|
<video v-if="boxNum == 4" id="videoPlayer2" :class="classStyle" autoplay="autoplay" loop="loop" muted
|
|
controls="controls"></video>
|
|
<video v-if="boxNum == 4" id="videoPlayer3" :class="classStyle" autoplay="autoplay" loop="loop" muted
|
|
controls="controls"></video>
|
|
<video v-if="boxNum == 4" id="videoPlayer4" :class="classStyle" autoplay="autoplay" loop="loop" muted
|
|
controls="controls"></video>
|
|
</div>
|
|
<!-- 违章识别 -->
|
|
<div class="vio-box">
|
|
<el-carousel height="200px" indicator-position="outside" :interval="100000" @change="loadVioInfos"
|
|
v-if="vioArr.length > 0">
|
|
<el-carousel-item v-for="(itemArr, arrIndex) in vioArr" :key="arrIndex">
|
|
<div class="vio-box-info layout">
|
|
<div class="vio-detail layout" v-for="(item, index) in itemArr" :key="index">
|
|
<div class="vio-img" v-if="!item.base64Url || item.base64Url.length < 32">
|
|
<el-image>
|
|
<div slot="error" class="image-slot">
|
|
<i class="el-icon-picture-outline"></i>
|
|
</div>
|
|
</el-image>
|
|
</div>
|
|
<div class="vio-img" v-if="item.base64Url && item.base64Url.length > 32">
|
|
<img :src="item.base64Url" alt="违章照片">
|
|
</div>
|
|
<div class="vio-content layout">
|
|
<span>{{ item.devName }}</span>
|
|
<span>{{ item.warnTime }}</span>
|
|
<span>{{ item.warnContent }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-carousel-item>
|
|
</el-carousel>
|
|
<el-empty v-if="vioArr.length == 0" :image-size="100" description="暂无违章数据"></el-empty>
|
|
</div>
|
|
</div>
|
|
<!-- 预警信息 -->
|
|
<div class="right">
|
|
<h4>预警信息</h4>
|
|
<div class="infinite-list-wrapper">
|
|
<ul class="list" v-infinite-scroll="loadWarnInfoData" infinite-scroll-disabled="busy"
|
|
infinite-scroll-distance="50">
|
|
<li v-for="(item, index) in warnInfoArr" :key="index" class="warn-li layout">
|
|
<span class="layout">{{ item.devTypeName }}</span>
|
|
<span class="layout">{{ item.devName }}</span>
|
|
<span class="layout">{{ item.warnTime }}</span>
|
|
<span class="layout">{{ item.warnContent }}</span>
|
|
</li>
|
|
<p v-if="loading" style="text-align: center;">加载中...</p>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { getBallDeviceLists, getPhotosById, getBallWarnLists, getWarnLists } from "@/api/construction/manage/realTimeManage.js";
|
|
export default {
|
|
name: 'realTimeManage',
|
|
/* 球机树前端筛选 */
|
|
watch: {
|
|
filterText(val) {
|
|
this.$refs.tree.filter(val);
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
// 球机树过滤
|
|
filterText: '',
|
|
//球机树数据
|
|
treeData: [],
|
|
// 球机树默认展示的节点
|
|
idArr: [],
|
|
// 查询参数
|
|
queryParams: {
|
|
pageNum: 0,
|
|
pageSize: 10
|
|
},
|
|
// 违章识别数组
|
|
vioArr: [],
|
|
splitScreenName: 'first',
|
|
//预警信息数据
|
|
warnInfoArr: [],
|
|
//预警是否加载
|
|
loading: false,
|
|
//预警滚动是否有数据
|
|
isHasData: true,
|
|
busy: true,
|
|
// 窗口数量
|
|
boxNum: 1,
|
|
classStyle: 'ball-content'
|
|
};
|
|
},
|
|
created() {
|
|
this.laodBallDeviceLists();
|
|
this.loadBallWarnLists();
|
|
},
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
this.busy = false;
|
|
});
|
|
},
|
|
methods: {
|
|
/* 加载球机树 */
|
|
laodBallDeviceLists() {
|
|
getBallDeviceLists().then(res => {
|
|
const treeData = res.data;
|
|
if (treeData && treeData.length > 0) {
|
|
this.treeData = treeData
|
|
// 设置默认展示球机层级
|
|
treeData.forEach(item => {
|
|
this.idArr.push(item.id);
|
|
})
|
|
}
|
|
}).catch(res => { });
|
|
},
|
|
/* 加载获取违章照片 */
|
|
async loadPhotosById(newIndex) {
|
|
if (this.vioArr.length === 0) {
|
|
return;
|
|
}
|
|
let filePathArr = [];
|
|
let arrData = this.vioArr[newIndex];
|
|
arrData.forEach(item => {
|
|
if (!item.isLoad) {
|
|
filePathArr.push(item.base64Url)
|
|
}
|
|
})
|
|
let obj = {
|
|
dataName: filePathArr
|
|
}
|
|
if (filePathArr.length > 0) {
|
|
await getPhotosById(obj).then(res => {
|
|
let photosData = res.data;
|
|
if (photosData && photosData.length > 0) {
|
|
this.vioArr[newIndex].forEach((item, index) => {
|
|
item.base64Url = photosData[index]
|
|
item.isLoad = true
|
|
});
|
|
}
|
|
})
|
|
}
|
|
},
|
|
/* 加载违章识别信息 */
|
|
loadBallWarnLists() {
|
|
getBallWarnLists().then(res => {
|
|
const data = res.data;
|
|
this.vioArr = data;
|
|
}).catch(res => { });
|
|
},
|
|
// 预警信息动态加载
|
|
loadWarnInfoData() {
|
|
if (!this.isHasData) {
|
|
return;
|
|
}
|
|
this.queryParams.pageNum = this.queryParams.pageNum + 1;
|
|
this.loading = true;
|
|
this.busy = true;
|
|
getWarnLists(this.queryParams).then(res => {
|
|
const data = res.data;
|
|
if (data && data.length > 0) {
|
|
data.forEach(item => {
|
|
this.warnInfoArr.push(item);
|
|
})
|
|
} else {
|
|
this.isHasData = false;
|
|
}
|
|
this.loading = false;
|
|
this.busy = false;
|
|
}).catch(res => {
|
|
this.loading = false;
|
|
this.busy = false;
|
|
});
|
|
},
|
|
/* 球机树过滤 */
|
|
filterNode(value, data, node) {
|
|
if (!value) {
|
|
if (node.level == 1) {
|
|
node.expanded = true
|
|
} else {
|
|
node.expanded = false
|
|
}
|
|
return true
|
|
}
|
|
// 查询列表是否有匹配数据
|
|
let val = value.toLowerCase()
|
|
return this.chooseNode(val, data, node)
|
|
},
|
|
// 过滤父节点 子节点:如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。
|
|
chooseNode(value, data, node) {
|
|
if (data.label.indexOf(value) !== -1) {
|
|
return true
|
|
}
|
|
const level = node.level
|
|
// 如果传入的节点本身就是一级节点就不用校验了
|
|
if (level === 1) {
|
|
return false
|
|
}
|
|
// 先取当前节点的父节点
|
|
let parentData = node.parent
|
|
// 遍历当前节点的父节点
|
|
let index = 0
|
|
while (index < level - 1) {
|
|
// 如果匹配到直接返回
|
|
if (parentData.data.label.indexOf(value) !== -1) {
|
|
return true
|
|
}
|
|
// 否则的话再往上一层做匹配
|
|
parentData = parentData.parent
|
|
index++
|
|
}
|
|
// 没匹配到返回false
|
|
return false
|
|
},
|
|
//球机树节点点击
|
|
handleNodeClick(data, node, item) {
|
|
if (node.level === 2) {
|
|
// 点击球机时触发的事件
|
|
}
|
|
},
|
|
// 轮播图切换时触发
|
|
loadVioInfos(newIndex, oldIndex) {
|
|
this.loadPhotosById(newIndex);
|
|
},
|
|
// 切换播放窗口
|
|
changePlayVideo(type) {
|
|
this.boxNum = type;
|
|
if (type == 1) {
|
|
this.classStyle = 'ball-content'
|
|
} else {
|
|
this.classStyle = 'ball-content-4'
|
|
}
|
|
},
|
|
//给tree不同层级设置不同的icon
|
|
renderContent(h, { node, data }) {
|
|
// 根据层级使用不同的图标
|
|
let icon;
|
|
if (node.level === 1) {
|
|
icon = 'pro_icon';
|
|
} else if (node.level === 2 && data.devStatus === 0) {
|
|
icon = 'ball_nocheck_icon';
|
|
} else if (node.level === 2 && data.devStatus === 1) {
|
|
icon = 'ball_check_icon';
|
|
}
|
|
return (
|
|
<span class="custom-tree-node">
|
|
<i class={icon}></i>
|
|
<span>{node.label}</span>
|
|
</span>
|
|
);
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.realTimeManage {
|
|
width: 100%;
|
|
height: 80vh;
|
|
background-color: #fff;
|
|
box-shadow: 10px 10px 5px #000;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.layout {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: start;
|
|
}
|
|
|
|
.realTimeManage .left {
|
|
width: 20%;
|
|
height: 100%;
|
|
padding: 0 0.5%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.cloud-platform-box {
|
|
width: 100%;
|
|
height: 35%;
|
|
justify-items: center;
|
|
justify-content: space-evenly;
|
|
}
|
|
|
|
#platform-left,
|
|
#platform-right {
|
|
width: 15%;
|
|
height: 52%;
|
|
margin-top: 40%;
|
|
align-items: center;
|
|
}
|
|
|
|
.common_size {
|
|
width: 32px;
|
|
height: 32px;
|
|
border: none;
|
|
cursor: pointer;
|
|
background-position: center center !important;
|
|
transition: background-image 0.5s;
|
|
}
|
|
|
|
.btn-desc {
|
|
writing-mode: vertical-lr;
|
|
margin: 8px 0;
|
|
letter-spacing: 2px;
|
|
}
|
|
|
|
.btn-desc2 {
|
|
margin: 0 8px;
|
|
letter-spacing: 2px;
|
|
}
|
|
|
|
#gq_nocheck {
|
|
background: url("../../../../assets/images/video/gq_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#gq_nocheck:hover {
|
|
background: url("../../../../assets/images/video/gq_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#gq2_nocheck {
|
|
background: url("../../../../assets/images/video/gq2_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
|
|
}
|
|
|
|
#gq2_nocheck:hover {
|
|
background: url("../../../../assets/images/video/gq2_check.png") no-repeat 0 0 /100% 100%;
|
|
|
|
}
|
|
|
|
#jj_nocheck {
|
|
background: url("../../../../assets/images/video/jj_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#jj_nocheck:hover {
|
|
background: url("../../../../assets/images/video/jj_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#yj_nocheck {
|
|
background: url("../../../../assets/images/video/yj_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#yj_nocheck:hover {
|
|
background: url("../../../../assets/images/video/yj_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#sx_nocheck {
|
|
background: url("../../../../assets/images/video/sx_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#sx_nocheck:hover {
|
|
background: url("../../../../assets/images/video/sx_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#fd_nocheck {
|
|
background: url("../../../../assets/images/video/fd_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#fd_nocheck:hover {
|
|
background: url("../../../../assets/images/video/fd_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#left_nocheck {
|
|
background: url("../../../../assets/images/video/left_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#left_nocheck:hover {
|
|
background: url("../../../../assets/images/video/left_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#right_nocheck {
|
|
background: url("../../../../assets/images/video/right_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#right_nocheck:hover {
|
|
background: url("../../../../assets/images/video/right_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#top_nocheck {
|
|
background: url("../../../../assets/images/video/top_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#top_nocheck:hover {
|
|
background: url("../../../../assets/images/video/top_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#bottom_nocheck {
|
|
background: url("../../../../assets/images/video/bottom_nocheck.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
#bottom_nocheck:hover {
|
|
background: url("../../../../assets/images/video/bottom_check.png") no-repeat 0 0 /100% 100%;
|
|
}
|
|
|
|
.fx-btn-box:nth-of-type(2) {
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.fx-btn-box:nth-of-type(2) button:nth-of-type(1) {
|
|
margin-top: 5px;
|
|
}
|
|
|
|
.fx-btn-box:nth-of-type(2) button:nth-of-type(2) {
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.left-right-btn-box {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: url("../../../../assets/images/video/left_btn.png") no-repeat;
|
|
background-position: center center !important;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
|
|
#platform-center {
|
|
width: 67%;
|
|
height: 100%;
|
|
}
|
|
|
|
#center-btn-top-box {
|
|
width: 100%;
|
|
height: 80%;
|
|
background: url("../../../../assets/images/video/back.png") no-repeat;
|
|
background-position: center center !important;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.fx-btn-box {
|
|
width: 20%;
|
|
height: 100%;
|
|
}
|
|
|
|
#center-btn-bottom-box {
|
|
width: 100%;
|
|
height: 20%;
|
|
background: url("../../../../assets/images/video/back3.png") no-repeat;
|
|
background-position: center center !important;
|
|
justify-content: center;
|
|
}
|
|
|
|
.tree-box {
|
|
width: 100%;
|
|
height: 65%;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.realTimeManage .center {
|
|
width: 48%;
|
|
height: 100%;
|
|
}
|
|
|
|
.change-box {
|
|
width: 100%;
|
|
height: 50px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.video-box {
|
|
width: 100%;
|
|
height: calc(100% - 275px);
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.ball-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
object-fit: fill;
|
|
}
|
|
|
|
.ball-content-4 {
|
|
width: 49.5%;
|
|
height: 49%;
|
|
pointer-events: none;
|
|
object-fit: fill;
|
|
}
|
|
|
|
.vio-box {
|
|
width: 100%;
|
|
height: 200px;
|
|
margin-top: 25px;
|
|
}
|
|
|
|
.vio-box-info {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.vio-detail {
|
|
width: 32%;
|
|
height: 100%;
|
|
margin-right: 1%;
|
|
flex-direction: column;
|
|
justify-content: start;
|
|
border: 1px solid #cccccc;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.vio-img {
|
|
width: 100%;
|
|
height: 60%;
|
|
}
|
|
|
|
.vio-img img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: fill;
|
|
}
|
|
|
|
.vio-content {
|
|
width: 100%;
|
|
height: 40%;
|
|
flex-direction: column;
|
|
justify-content: space-evenly;
|
|
|
|
}
|
|
|
|
.realTimeManage .right {
|
|
width: 30%;
|
|
height: 100%;
|
|
}
|
|
|
|
.warn-li {
|
|
width: 100%;
|
|
height: 75px;
|
|
border-bottom: 1px solid #cccccc;
|
|
}
|
|
|
|
.warn-li span {
|
|
width: 25%;
|
|
height: 100%;
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
/* tree节点过长换行处理 */
|
|
.tree {
|
|
width: 100%;
|
|
|
|
::v-deep .el-tree-node {
|
|
white-space: normal;
|
|
|
|
.el-tree-node__content {
|
|
height: 100%;
|
|
align-items: center;
|
|
margin: 4px 0;
|
|
}
|
|
}
|
|
|
|
::v-deep .el-tree-node__label {
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
|
|
::v-deep .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
|
|
color: #1890ff;
|
|
}
|
|
|
|
ul {
|
|
padding-inline-start: 0;
|
|
}
|
|
|
|
.infinite-list-wrapper {
|
|
height: 90%;
|
|
margin-bottom: 10%;
|
|
overflow: auto;
|
|
}
|
|
|
|
::v-deep .pro_icon,
|
|
::v-deep .ball_nocheck_icon,
|
|
::v-deep .ball_check_icon {
|
|
vertical-align: top;
|
|
background-size: cover;
|
|
background-position: center;
|
|
display: inline-block;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
::v-deep .pro_icon {
|
|
background-image: url("../../../../assets/images/pro_icon.png") !important;
|
|
width: 20px;
|
|
height: 20px;
|
|
|
|
}
|
|
|
|
::v-deep .ball_nocheck_icon {
|
|
background-image: url("../../../../assets/images/ball_nocheck_icon.png") !important;
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
::v-deep .ball_check_icon {
|
|
background-image: url("../../../../assets/images/ball_check_icon.png") !important;
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
</style> |