From d20fcd6ad28a534d763273c48381cdc36ff2891f Mon Sep 17 00:00:00 2001
From: web <candymxq888@outlook.com>
Date: 星期六, 19 四月 2025 17:25:44 +0800
Subject: [PATCH] fix:对接监控视频

---
 src/views/screen/flow/graphic/index.vue |  354 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 205 insertions(+), 149 deletions(-)

diff --git a/src/views/screen/flow/graphic/index.vue b/src/views/screen/flow/graphic/index.vue
index 6bf1245..47b28aa 100644
--- a/src/views/screen/flow/graphic/index.vue
+++ b/src/views/screen/flow/graphic/index.vue
@@ -1,191 +1,207 @@
 <script setup>
-import {ref} from "vue";
+import {onMounted, ref, onUnmounted} from "vue";
 import {getUserType} from '@/utils/auth.js'
-import html2canvas from "html2canvas";
+import {getFlowPointList} from '@/api/screen/index'
+import {getFlowVideoData} from '@/api/screen/graphic/index.js'
+import EZUIKit from 'ezuikit-js';
+import {useRoute} from "vue-router";
 
+const route = useRoute();
+
+const menuList = ref([])
 const userType = ref(getUserType())
-const monitorRef = ref()
 const searchVal = ref('')
-const selectType = ref(1);
-const typeOption = ref([
-    { label: '水电站流量监测点', value: 1 },
-    { label: '新扎口流量监测点', value: 2 },
-])
-const video = ref()
+const playerData = ref([])
+const hasFullScreen = ref(false)
+let ezKitList = []; //视频组件实例数组
+let ezKitId = []; //视频盒子id数组
+let timer = null;
 
 // 全屏操作
 const handleFullScreen = () => {
-    monitorRef.value.requestFullscreen()
+    const dom = document.getElementById(ezKitId[0])
+    dom.requestFullscreen()
 }
+
+// 监听全屏状态,是否要开起蒙层
+document.addEventListener('fullscreenchange', (val) => {
+    if (!document.fullscreenElement) {  //退出全屏
+        hasFullScreen.value = false;
+    } else { //开起全屏
+        hasFullScreen.value = true;
+    }
+});
 
 // 抓拍
-const handleSnap = () => {
-    if(video.value) {
-        html2canvas(video.value).then(canvas => {
-            const link = document.createElement("a");
-            link.href = canvas.toDataURL("image/png");
-            link.download = '截图.png';
-            link.click()
-        })
-    }
+const handleSnap = (index) => {
+    ezKitList[index].capturePicture(`capture-${new Date().getTime()}`, 0.8); // 参数:回调函数,图片格式,质量(0-1)
 }
 
+// 获取监控点菜单
+const getMoitorList = () => {
+    getFlowPointList().then(res => {
+        menuList.value = res.data
+    })
+}
+
+// 选择菜单
+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)
+    }
+})
 </script>
 
 <template>
     <div class="graphic">
         <div class="graphic-menu">
             <div class="menu-t">监控点列表</div>
-            <el-menu class="el-menu">
-                <el-sub-menu index="1">
-                    <template #title>
-                        <span>可移动监测点</span>
+            <el-menu class="el-menu" @select="handleSelect">
+                <template v-for="(item, index) in menuList" :key="index+1">
+                    <template v-if="item?.childrenList?.length === 0">
+                        <el-menu-item :index="item.id">{{ item.pointName }}</el-menu-item>
                     </template>
-                    <el-menu-item index="1-1">水电站流量监测点</el-menu-item>
-                </el-sub-menu>
-                <el-sub-menu index="2">
-                    <template #title>
-                        <span>固定位监测点</span>
+                    <template v-else>
+                        <el-sub-menu :index="item.id">
+                            <template #title>
+                                <span>{{ item.pointName }}</span>
+                            </template>
+                            <el-menu-item v-for="(child, cidx) in item.childrenList" :key="cidx" :index="child.id">
+                                {{ child.pointName }}
+                            </el-menu-item>
+                        </el-sub-menu>
                     </template>
-                    <el-menu-item index="2-1">新扎口流量监测点</el-menu-item>
-                </el-sub-menu>
+                </template>
             </el-menu>
         </div>
         <div class="graphic-monitor">
             <div class="monitor-tool">
                 <div class="tool-l">
-                    <div class="name">监测点类型</div>
-                    <el-select
-                        v-model="selectType"
-                        class="tool-select"
-                        placeholder="Select"
-                        style="width: 15rem"
-                    >
-                        <el-option
-                            v-for="item in typeOption"
-                            :key="item.value"
-                            :label="item.label"
-                            :value="item.value"
-                        />
-                    </el-select>
-                    <el-input v-model="searchVal" style="width: 20rem" />
-                    <el-button><el-icon><Search /></el-icon>搜索</el-button>
-                    <el-button style="margin-left: 0" v-if="userType === '1'"><el-icon><Plus /></el-icon>新增</el-button>
+                    <el-input v-model="searchVal" style="width: 20rem" placeholder="请输入监测点名称" clearable/>
+                    <el-button @click="handleSearch">
+                        <el-icon>
+                            <Search/>
+                        </el-icon>
+                        搜索
+                    </el-button>
+                    <el-button style="margin-left: 0" v-if="userType === '1'">
+                        <el-icon>
+                            <Plus/>
+                        </el-icon>
+                        新增
+                    </el-button>
                 </div>
                 <div class="tool-r" @click="handleFullScreen">
-                    <img src="@/assets/images/flow/fullscreen.png" />
+                    <img src="@/assets/images/flow/fullscreen.png"/>
                     全屏
                 </div>
             </div>
-            <div class="monitor-box" ref="monitorRef">
+            <div class="monitor-box">
                 <div class="monitor-list">
-                    <div class="item">
-                        <div class="title">新扎口流量监测点</div>
-                        <div class="videoBox" ref="video"></div>
+                    <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="info">
                             <div class="info-list">
                                 <div class="info-item">
                                     <div class="name">水位:</div>
-                                    <div class="val"><span>2332</span>m</div>
+                                    <div class="val"><span>{{ item.waterLevel }}</span>m</div>
                                 </div>
                                 <div class="info-item">
-                                    <div class="name">表面流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
+                                    <div class="name">流速:</div>
+                                    <div class="val"><span>{{ item.flowVelocity }}</span>m/s</div>
                                 </div>
                                 <div class="info-item">
-                                    <div class="name">水面宽度:</div>
-                                    <div class="val"><span>100</span>m</div>
+                                    <div class="name">瞬时流量:</div>
+                                    <div class="val"><span>{{ item.newFlow }}</span>m³/h</div>
                                 </div>
                                 <div class="info-item">
-                                    <div class="name">平均流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">过水面积:</div>
-                                    <div class="val"><span>30</span>㎡</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">雷达流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">实时流速:</div>
-                                    <div class="val"><span>120</span>㎡/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">起点距:</div>
-                                    <div class="val"><span>500</span>m</div>
+                                    <div class="name">累计流量:</div>
+                                    <div class="val"><span>{{ item.totalFlow }}</span>m³</div>
                                 </div>
                             </div>
                             <div class="info-btn">
-                                <el-button style="width: 6rem" @click="handleSnap">抓拍</el-button>
-                            </div>
-                        </div>
-                    </div>
-                    <div class="item">
-                        <div class="title">新扎口流量监测点</div>
-                        <div class="videoBox"></div>
-                        <div class="info">
-                            <div class="info-list">
-                                <div class="info-item">
-                                    <div class="name">水位:</div>
-                                    <div class="val"><span>2332</span>m</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">表面流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">水面宽度:</div>
-                                    <div class="val"><span>100</span>m</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">平均流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">过水面积:</div>
-                                    <div class="val"><span>30</span>㎡</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">雷达流速:</div>
-                                    <div class="val"><span>4.5</span>m/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">实时流速:</div>
-                                    <div class="val"><span>120</span>㎡/s</div>
-                                </div>
-                                <div class="info-item">
-                                    <div class="name">起点距:</div>
-                                    <div class="val"><span>500</span>m</div>
-                                </div>
-                            </div>
-                            <div class="info-btn">
-                                <el-button style="width: 6rem">抓拍</el-button>
+                                <el-button style="width: 6rem" @click="handleSnap(index)">抓拍</el-button>
                             </div>
                         </div>
                     </div>
                 </div>
             </div>
         </div>
+        <div class="mask" v-show="hasFullScreen">
+            <div class="mask-item"></div>
+        </div>
     </div>
 </template>
 
 <style scoped lang="scss">
-.graphic{
+.graphic {
     height: 100%;
     display: flex;
-    &-menu{
+
+    &-menu {
         flex-shrink: 0;
         width: 20%;
         height: 100%;
         padding: 10px 0;
-        background: linear-gradient( 135deg, #91BDDB 0%, #9EC2DB 99%);
+        background: linear-gradient(135deg, #91BDDB 0%, #9EC2DB 99%);
         overflow-y: scroll;
+
         &::-webkit-scrollbar {
             display: none;
         }
-        .menu-t{
+
+        .menu-t {
             height: 40px;
             line-height: 40px;
             padding-left: 20px;
@@ -194,111 +210,134 @@
             background: url("@/assets/images/flow/monitor-title-bg.png") no-repeat;
             background-size: 100% 100%;
         }
-        .el-menu{
+
+        .el-menu {
             background-color: transparent;
             border-right: none;
-            :deep(.el-menu){
+
+            :deep(.el-menu) {
                 background-color: transparent;
             }
+
             :deep(.el-sub-menu__title:hover) {
                 background-color: rgba(0, 0, 0, 0.06);
             }
+
             :deep(.el-menu-item.is-active) {
                 color: #fff;
             }
         }
     }
-    &-monitor{
+
+    &-monitor {
         flex-shrink: 0;
         width: 80%;
         height: 100%;
-        background: linear-gradient( 180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%);
-        .monitor-tool{
+
+        .monitor-tool {
             width: 100%;
             height: 60px;
             padding: 0 30px;
-            background: linear-gradient( 90deg, #91BDDB 0%, #DADFE3 100%);
+            background: linear-gradient(90deg, #91BDDB 0%, #DADFE3 100%);
             display: flex;
             align-items: center;
             justify-content: space-between;
-            .tool-l{
+
+            .tool-l {
                 display: flex;
                 align-items: center;
                 gap: 1rem;
-                .name{
+
+                .name {
                     font-size: 1.1rem;
                 }
             }
-            .tool-r{
+
+            .tool-r {
                 display: flex;
                 align-items: center;
-                img{
+
+                img {
                     width: 25px;
                     margin-right: 10px;
                 }
             }
         }
-        .monitor-box{
+
+        .monitor-box {
             height: calc(100% - 60px);
-            .monitor-list{
+            background: linear-gradient(180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%);
+
+            .monitor-list {
                 height: 100%;
                 display: flex;
                 align-items: center;
                 justify-content: space-between;
                 padding: 0 30px;
-                .item{
+
+                .item {
                     width: 48%;
                     height: 96%;
-                    background: rgba(23,108,229,0.3);
+                    background: rgba(23, 108, 229, 0.3);
                     border: 1px solid #176CE5;
                     padding: 20px;
-                    .title{
+                    border-radius: 8px;
+
+                    .title {
                         height: 12%;
                         text-align: center;
                         font-size: 42px;
                         color: #fff;
                     }
-                    .videoBox{
+
+                    .videoBox {
                         width: 100%;
                         height: 60%;
-                        background: url("@/assets/images/login_icon.png") no-repeat;
+                        background-color: #000;
                     }
-                    .info{
+
+                    .info {
                         width: 100%;
                         height: 25%;
                         display: flex;
                         margin-top: 20px;
-                        .info-list{
+
+                        .info-list {
                             width: 80%;
                             display: flex;
                             flex-wrap: wrap;
                             color: #fff;
                             font-size: 20px;
-                            .info-item{
+
+                            .info-item {
                                 width: 50%;
                                 padding: 8px 0;
                                 flex-shrink: 0;
                                 display: flex;
                                 align-items: center;
-                                .name{
+
+                                .name {
                                     width: 100px;
                                 }
-                                .val span{
+
+                                .val span {
                                     display: inline-block;
                                     padding: 0 20px;
                                 }
                             }
                         }
-                        .info-btn{
+
+                        .info-btn {
                             width: 20%;
                             padding: 1rem 0;
                             display: flex;
                             align-items: flex-end;
-                            :deep(.el-button){
+
+                            :deep(.el-button) {
                                 color: #fff;
-                                background: rgba(94,229,92,0.6);
+                                background: rgba(94, 229, 92, 0.6);
                                 border-radius: 4px 4px 4px 4px;
-                                border: 1px solid rgba(94,229,92,0.6);
+                                border: 1px solid rgba(94, 229, 92, 0.6);
                             }
                         }
                     }
@@ -306,5 +345,22 @@
             }
         }
     }
+
+    .mask{
+        position: absolute;
+        left: 0;
+        top: 0;
+        z-index: 100;
+        width: 100vw;
+        height: 100vh;
+        .mask-item{
+            position: absolute;
+            left: 5%;
+            bottom: 10%;
+            height: 400px;
+            width: 300px;
+            background-color: rgba(0, 0, 0, 0.4);
+        }
+    }
 }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3