| | |
| | | <script setup> |
| | | import {onMounted, ref, onUnmounted} from "vue"; |
| | | import {onMounted, ref} from "vue"; |
| | | import {getUserType} from '@/utils/auth.js' |
| | | import {getFlowPointList} from '@/api/screen/index' |
| | | import {getFlowVideoData} from '@/api/screen/graphic/index.js' |
| | | import EZUIKit from 'ezuikit-js'; |
| | | import {useRoute, useRouter} from "vue-router"; |
| | | import FullScreenVideo from "./components/FullScreenVideo.vue"; |
| | | import VideoPlayer from "@/components/VideoPlayer/VideoPlayer.vue"; |
| | | import html2canvas from 'html2canvas'; |
| | | |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | |
| | | const userType = ref(getUserType()) |
| | | const searchVal = ref('') |
| | | const playerData = ref([]) |
| | | const hasFullScreen = ref(false) |
| | | const showFullScreen = ref(false) |
| | | const fullIndex = ref() |
| | | let ezKitList = []; //视频组件实例数组 |
| | | let ezKitId = []; //视频盒子id数组 |
| | | let timer = null; |
| | | |
| | | // 全屏弹窗 |
| | | const handleFullScreen = (index) => { |
| | | fullIndex.value = index; |
| | | hasFullScreen.value = true; |
| | | fullIndex.value = index |
| | | showFullScreen.value = true |
| | | } |
| | | |
| | | // 关闭全屏弹窗 |
| | | const closeFullScreen = () => { |
| | | hasFullScreen.value = false; |
| | | showFullScreen.value = false |
| | | } |
| | | |
| | | // 抓拍 |
| | | const handleSnap = (index) => { |
| | | ezKitList[index].capturePicture(`capture-${new Date().getTime()}`, 0.8); |
| | | const handleSnap = async (index) => { |
| | | const dom = document.getElementById(`player${index}`) |
| | | const canvas = await html2canvas(dom, { |
| | | backgroundColor: null, // 透明背景 |
| | | scale: 2, // 提高分辨率 |
| | | logging: false, // 关闭日志 |
| | | useCORS: true, // 允许跨域图片 |
| | | allowTaint: true, // 允许污染图片 |
| | | }); |
| | | const imgUrl = canvas.toDataURL('image/png'); |
| | | const adom = document.createElement("a"); |
| | | adom.download = `截图_${new Date().getTime()}.png` |
| | | adom.href = imgUrl; |
| | | adom.click() |
| | | } |
| | | |
| | | // 获取监控点菜单 |
| | |
| | | |
| | | // 选择菜单 |
| | | const handleSelect = (id) => { |
| | | ezKitList = [] |
| | | ezKitId = [] |
| | | playerData.value = [] |
| | | clearInterval(timer) |
| | | getPlayerList(id) |
| | | } |
| | | |
| | | // 搜索 |
| | | const handleSearch = () => { |
| | | ezKitList = [] |
| | | ezKitId = [] |
| | | playerData.value = [] |
| | | clearInterval(timer) |
| | | getPlayerList() |
| | | } |
| | | |
| | | // 获取监控点 |
| | | const getPlayerList = async (id) => { |
| | | getFlowVideoData({pointId: id, pointName: searchVal.value}).then(async res => { |
| | | res.data.forEach((item, index) => { |
| | | ezKitId[index] = `ezuikitPlayer${index}` |
| | | }) |
| | | playerData.value = res.data |
| | | await nextTick() |
| | | |
| | | // 渲染视频 |
| | | res.data.forEach((item, index) => { |
| | | ezKitList[index] = new EZUIKit.EZUIKitPlayer({ |
| | | id: ezKitId[index], |
| | | url: item.url, |
| | | accessToken: item.accessToken, |
| | | }) |
| | | }) |
| | | }) |
| | | |
| | | // 挂载定时器, 只获取数据,不重新渲染视频节点 |
| | | timer = setInterval(() => { |
| | | getFlowVideoData({pointId: id, pointName: searchVal.value}).then(res => { |
| | | playerData.value = res.data |
| | | }) |
| | | }, 10000) |
| | | } |
| | | |
| | | |
| | | onMounted(() => { |
| | | getMoitorList() |
| | | getPlayerList(route.params.id || '') |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | | if (timer) { |
| | | clearInterval(timer) |
| | | } |
| | | // 停止播放 |
| | | ezKitList?.forEach(item => { |
| | | item.stop(); |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | |
| | | <div class="monitor-list"> |
| | | <div class="item" v-for="(item, index) in playerData" :key="index"> |
| | | <div class="title">{{ item.pointName }}</div> |
| | | <div class="videoBox" :id="ezKitId[index]"></div> |
| | | <div class="item-video" :id="`player${index}`"> |
| | | <VideoPlayer :item="item" :autoPlay="true" /> |
| | | </div> |
| | | <div class="info"> |
| | | <div class="info-list"> |
| | | <div class="info-item"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <FullScreenVideo |
| | | v-if="hasFullScreen" |
| | | :data="playerData[fullIndex]" |
| | | @close="closeFullScreen" |
| | | /> |
| | | |
| | | <div class="fullDialog" v-if="showFullScreen"> |
| | | <VideoPlayer :item="playerData[fullIndex]" :autoPlay="true" /> |
| | | <div class="closeIcon" @click="closeFullScreen"><el-icon><CircleClose /></el-icon></div> |
| | | <div class="full-mask"> |
| | | <div class="mask-list"> |
| | | <div class="mask-item"> |
| | | <div class="name">水位:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].waterLevel }}</span>m</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">表面流速:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].flowVelocity }}</span>m/s</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">水面宽度:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].waterWidth }}</span>m</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">平均流速:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].avgVelocity }}</span>m/s</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">过水面积:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].waterArea }}</span>m³</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">雷达流速:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].radarVelocity }}</span>m/s</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">实时流量:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].newFlow }}</span>m³/h</div> |
| | | </div> |
| | | <div class="mask-item"> |
| | | <div class="name">起点距:</div> |
| | | <div class="val"><span>{{ playerData[fullIndex].radarDistance }}</span>m</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | color: #fff; |
| | | } |
| | | |
| | | .videoBox { |
| | | .item-video { |
| | | width: 100%; |
| | | height: 60%; |
| | | background-color: #000; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .fullDialog{ |
| | | position: fixed; |
| | | left: 0; |
| | | top: 0; |
| | | z-index: 200; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: #000; |
| | | .closeIcon{ |
| | | position: absolute; |
| | | right: 20px; |
| | | top: 20px; |
| | | color: #fff; |
| | | font-size: 36px; |
| | | } |
| | | .full-mask{ |
| | | position: absolute; |
| | | left: 100px; |
| | | bottom: 100px; |
| | | width: 250px; |
| | | height: 270px; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | border-radius: 20px; |
| | | .mask-list{ |
| | | padding: 10px 20px; |
| | | .mask-item{ |
| | | display: flex; |
| | | align-items: center; |
| | | color: #fff; |
| | | padding: 5px 0; |
| | | .name{ |
| | | width: 50%; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |