Procházet zdrojové kódy

Merge branch 'master' of http://182.92.126.35:3000/hrx/mky-vent-base

lxh před 1 rokem
rodič
revize
3a807b4229

+ 0 - 1
src/components/Table/src/components/TableAction.vue

@@ -139,7 +139,6 @@
       }
 
       function onCellClick(e: MouseEvent) {
-        debugger
         if (!props.stopButtonPropagation) return;
         const path = e.composedPath() as HTMLElement[];
         const isInButton = path.find((ele) => {

+ 12 - 6
src/design/vent/comment.less

@@ -200,13 +200,19 @@
   }
 }
 #LivePlayerBox{
-  .player{
-    width: 314px;
-    height: 208px;
-    padding: 10px;
-    background: url('/@/assets/images/vent/camera_bg.png');
-    background-size: cover;
+  width: 100%;
+  height: auto;
+  .liveVideo{
+    pointer-events: auto !important;
+    .player {
+        width: 314px;
+        height: 208px;
+        padding: 10px;
+        background: url('/@/assets/images/vent/camera_bg.png');
+        background-size: cover;
+      }
   }
+ 
 }
 
 @keyframes breathe {

+ 38 - 0
src/hooks/event/useDrag.ts

@@ -0,0 +1,38 @@
+export function useDrag(sliderDom: HTMLElement) {
+  let startPoint = 0;
+  let isDown = false;
+  let premitiveX = 0;
+  function onMouseDown(e: any) {
+    isDown = true;
+    const style = window.getComputedStyle(sliderDom!);
+    const { transform } = style;
+    if (transform !== 'none') {
+      const matrixArr = transform.replace(/[^0-9\-,]/g, '').split(',');
+      console.log('matrixArr', matrixArr);
+      premitiveX = parseInt(matrixArr[4]);
+    } else {
+      premitiveX = 0;
+    }
+    const { clientX } = e;
+    startPoint = clientX;
+  }
+
+  function onMosueUp(e: any) {
+    isDown = false;
+  }
+
+  function onMouseMove(e: any) {
+    if (!isDown) return;
+    const { clientX } = e;
+    const moveDistance = clientX - startPoint;
+    const offset = premitiveX + moveDistance;
+    console.log('offset', offset);
+    sliderDom!.style.transform = `translateX(${offset}px)`;
+  }
+
+  sliderDom.addEventListener('mouseDown', onMouseDown);
+  sliderDom.addEventListener('mouseMove', onMouseMove);
+  sliderDom.addEventListener('mouseUp', onMosueUp);
+
+  return { onMouseDown, onMouseMove, onMosueUp };
+}

+ 227 - 0
src/hooks/system/useCamera.ts

@@ -0,0 +1,227 @@
+import { defHttp } from '/@/utils/http/axios';
+import { render, h, nextTick } from 'vue';
+import LivePlayer from '@liveqing/liveplayer-v3';
+import { useDrag } from '../event/useDrag';
+
+export function useCamera() {
+  const cameraList = (params) => defHttp.get({ url: '/safety/ventanalyCamera/list', params });
+  const cameraAddrList = (params) => defHttp.post({ url: '/ventanaly-device/camera/info', params });
+
+  let webRtcServer = <any[]>[];
+  let playerDoms = <(HTMLVideoElement | undefined | null)[]>[];
+
+  async function getCamera(deviceid, parentPlayerDom?) {
+    if (!parentPlayerDom) {
+      parentPlayerDom = document.createElement('div');
+      parentPlayerDom.setAttribute('style', `top:0px; left: 0px; width: 100%; height: 100%; position: fixed; z-index: 999;`);
+    }
+    const res = await cameraList({ deviceid });
+    const cameras: [] = res.records || [];
+    let cameraAddrs: any[] = [],
+      cameraNames: string[] = [];
+    if (cameras.length > 0) {
+      cameras.forEach((item) => {
+        if (item['devicekind'] == 'toRtsp' || item['devicekind'] == 'toHLS') {
+          cameraNames.push(item['name']);
+        } else {
+          cameraAddrs.push({ name: item['name'], addr: item['addr'] });
+        }
+      });
+    }
+    if (cameraNames.length > 0) {
+      // 请求接口从装备院拿数据
+      const addrs: string[] = await cameraAddrList({ cameraNameList: cameraNames });
+      for (let i = 0; i < addrs.length; i++) {
+        cameraAddrs.push({ name: '摄像头' + i, addr: addrs[i] });
+      }
+    }
+
+    const obj = await deviceCameraInit(cameraAddrs, parentPlayerDom, webRtcServer);
+    webRtcServer = obj.webRtcServerList;
+    playerDoms = obj.playerDoms;
+  }
+
+  function deviceCameraInit(cameraAddrs, player: HTMLElement, webRtcServerList: any[] = []) {
+    const playerDoms: (HTMLVideoElement | undefined | null)[] = [];
+    const webRtcServer: any[] = [];
+    let livePlayerDiv: HTMLElement | null = document.getElementById('LivePlayerBox');
+    if (livePlayerDiv) {
+      livePlayerDiv.remove();
+      livePlayerDiv = null;
+    }
+    if (!livePlayerDiv) {
+      const dom = document.createElement('div');
+      dom.setAttribute('id', 'LivePlayerBox');
+      livePlayerDiv = dom;
+      player.appendChild(livePlayerDiv);
+    }
+    const videoParentDomList: (HTMLElement | [string, { name: string; addr: string }])[] = [];
+    return new Promise((resolve) => {
+      const playCamrea = () => {
+        if (cameraAddrs.length > 0) {
+          const promiseList: Promise<any>[] = [];
+          cameraAddrs.forEach(async (cameraUrl: { name: string; addr: string }, index) => {
+            const promise = new Promise(async (childResolve) => {
+              let cameraNameDom: null | HTMLElement = null;
+              console.log('摄像头地址--------->', cameraUrl, cameraUrl.addr.startsWith('rtsp://'), livePlayerDiv);
+              if (cameraUrl.addr && cameraUrl.addr.startsWith('rtsp://')) {
+                const server = webRtcServerList.shift();
+                if (server) {
+                  try {
+                    const videoElement = server.videoElement as HTMLVideoElement;
+                    videoElement.volume = 0;
+                    const cameraNameDom = videoElement.parentElement?.getElementsByClassName('video-name')[0];
+                    if (cameraNameDom) cameraNameDom.innerText = cameraUrl.name;
+                    playerDoms.unshift(videoElement);
+                    webRtcServer.unshift(server);
+                    await server.connect(cameraUrl['addr']);
+                    videoElement.play();
+                    childResolve(null);
+                  } catch (error) {
+                    playerDoms.unshift(undefined);
+                    childResolve(null);
+                  }
+                } else {
+                  const videoParentDom: HTMLElement = document.createElement('div');
+                  videoParentDom.setAttribute('class', 'video-parent');
+                  const videoDom: HTMLVideoElement = document.createElement('video');
+                  videoDom.volume = 0;
+                  videoDom.setAttribute('class', 'rtspVideo');
+                  videoDom.setAttribute('muted', 'muted');
+                  videoDom.setAttribute('poster', '/src/assets/images/vent/noSinge.png');
+                  videoDom.autoplay = true;
+                  videoParentDom.appendChild(videoDom);
+                  cameraNameDom = document.createElement('div');
+                  cameraNameDom.setAttribute('class', 'video-name');
+                  cameraNameDom.innerText = cameraUrl.name;
+                  videoParentDom.appendChild(cameraNameDom);
+                  videoParentDom.addEventListener('dblclick', () => {
+                    if (videoDom.requestFullscreen) {
+                      videoDom.requestFullscreen();
+                      videoDom.play();
+                    }
+                  });
+
+                  videoParentDomList.push(videoParentDom);
+                  livePlayerDiv?.appendChild(videoParentDom);
+                  try {
+                    const server = new window['WebRtcStreamer'](videoDom, location.protocol + VUE_APP_URL.webRtcUrl);
+                    webRtcServer.unshift(server);
+                    await server.connect(cameraUrl.addr);
+                    videoDom.play();
+                    playerDoms.unshift(videoDom);
+                    childResolve(null);
+                  } catch (error) {
+                    console.log('WebRtcStreamer 抛出异常!!!!!!');
+                    playerDoms.unshift(null);
+                    childResolve(null);
+                  }
+                }
+              } else {
+                try {
+                  fetch(cameraUrl.addr, {
+                    method: 'get',
+                    mode: 'no-cors',
+                  })
+                    .then(() => {
+                      videoParentDomList.push(['player', cameraUrl]);
+                      childResolve(null);
+                    })
+                    .catch(() => {
+                      videoParentDomList.push(['onPlayer' + index, cameraUrl]);
+                      childResolve(null);
+                    });
+                } catch (error) {
+                  // console.log('可以捕获到异常吗?????');
+                  childResolve(null);
+                }
+              }
+            });
+            promiseList.push(promise);
+          });
+          Promise.all(promiseList).then(() => {
+            resolve(null);
+          });
+        } else {
+          resolve(null);
+        }
+      };
+      playCamrea();
+    }).then(() => {
+      videoParentDomList.forEach((videoParentDom) => {
+        if (typeof videoParentDom[0] === 'string' && livePlayerDiv) {
+          const videoDom: HTMLElement = document.createElement('div');
+          videoDom.setAttribute('class', 'liveVideo');
+          livePlayerDiv?.appendChild(videoDom);
+          useDrag(videoDom);
+
+          if (videoParentDom[0].startsWith('onPlayer')) {
+            render(
+              h(LivePlayer, {
+                class: 'player',
+                id: videoParentDom[0],
+                muted: 'muted',
+                autoplay: true,
+                live: true,
+                videoUrl: videoParentDom[1].addr,
+                videoTitle: videoParentDom[1].name,
+                alt: '无信号',
+                poster: '/src/assets/images/vent/noSinge.png',
+              }),
+              videoDom
+            );
+          } else {
+            render(
+              h(LivePlayer, {
+                class: 'player',
+                muted: 'muted',
+                autoplay: true,
+                live: true,
+                videoUrl: videoParentDom[1].addr,
+                videoTitle: videoParentDom[1].name,
+                alt: '无信号',
+                poster: '/src/assets/images/vent/noSinge.png',
+              }),
+              videoDom
+            );
+          }
+        } else {
+          player.appendChild(videoParentDom as Node);
+        }
+      });
+
+      const players = livePlayerDiv?.getElementsByClassName('player');
+      if (players && players.length) {
+        for (let i = 0; i < players.length; i++) {
+          try {
+            const isCanPlayer = !players[i].getAttribute('id')?.startsWith('onPlayer');
+            const dom = players[i].getElementsByTagName('video')[0];
+            if (dom && isCanPlayer) {
+              playerDoms.unshift(dom);
+            } else {
+              playerDoms.unshift(null);
+            }
+          } catch (error) {
+            console.log('可以捕获到异常吗?????');
+            playerDoms.unshift(null);
+          }
+        }
+      }
+      if (webRtcServerList.length > 0) {
+        for (let i = 0; i < webRtcServerList.length; i++) {
+          webRtcServerList[i].videoElement.parentElement.remove();
+          webRtcServerList[i].disconnect();
+          webRtcServerList[i] = undefined;
+        }
+      }
+      return { webRtcServerList: webRtcServer, playerDoms };
+    });
+  }
+
+  return {
+    getCamera,
+    webRtcServer,
+    playerDoms,
+    deviceCameraInit,
+  };
+}

+ 4 - 2
src/utils/ventutil.ts

@@ -158,6 +158,8 @@ export function deviceCameraInit(cameraAddrs, player: HTMLElement, webRtcServerL
   }).then(() => {
     videoParentDomList.forEach((videoParentDom) => {
       if (typeof videoParentDom[0] === 'string') {
+        const videoDom: HTMLElement = document.createElement('div');
+        livePlayerDiv?.appendChild(videoDom);
         if (videoParentDom[0].startsWith('onPlayer')) {
           render(
             h(LivePlayer, {
@@ -171,7 +173,7 @@ export function deviceCameraInit(cameraAddrs, player: HTMLElement, webRtcServerL
               alt: '无信号',
               poster: '/src/assets/images/vent/noSinge.png',
             }),
-            livePlayerDiv
+            videoDom
           );
         } else {
           render(
@@ -185,7 +187,7 @@ export function deviceCameraInit(cameraAddrs, player: HTMLElement, webRtcServerL
               alt: '无信号',
               poster: '/src/assets/images/vent/noSinge.png',
             }),
-            livePlayerDiv
+            videoDom
           );
         }
       } else {

+ 1 - 1
src/views/vent/monitorManager/deviceMonitor/components/device/index.vue

@@ -606,7 +606,7 @@ function goDetail(record?) {
       const newPage = router.resolve({ path: '/monitorChannel/monitor-fanmain', query: { id: activeID.value } })
       window.open(newPage.href, '_blank')
     } else if (deviceType.value.indexOf("fanlocal") != -1) {
-      const newPage = router.resolve({ path: '/monitorChannel/monitor-fanlocal', query: { id: activeID.value } })
+      const newPage = router.resolve({ path: '/monitorChannel/monitor-fanlocal', query: { id: activeID.value, deviceType: deviceType.value } })
       window.open(newPage.href, '_blank')
     } else if (deviceType.value.indexOf("pulping") != -1) {
       const newPage = router.resolve({ path: '/grout-home', query: { id: activeID.value } })

+ 24 - 11
src/views/vent/monitorManager/fanLocalMonitor/index.vue

@@ -54,8 +54,7 @@
     <div class="title-text">
       {{ selectData.supplyAirAddr||selectData.stationname }}
     </div>
-    <div class="data-show-box" v-if="!loading">
-      
+    <div class="data-show-box" v-if="!loading"> 
       <div class="data-item"> 
           <div class="item-header">环境监测</div>
           <div class="item-container">
@@ -252,10 +251,10 @@
       </dv-border-box8>
     </div>
   </div>
-  <div style="z-index: -1; position: absolute; top: 50px; right: 10px; width: 300px; height: 280px; margin: auto" class="player1">
+  <!-- <div style="z-index: -1; position: absolute; top: 50px; right: 10px; width: 300px; height: 280px; margin: auto" class="player1">
     <LivePlayer id="jb-player1" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
-  </div>
-  <div ref="playerRef" style="z-index: 999; position: absolute; top: 100px; right: 15px; width: 300px; height: 280px; margin: auto">
+  </div> -->
+  <div ref="playerRef" style="z-index: 999; position: absolute; top: 100px; right: 15px; width: 100%; height: 100%; margin: auto; pointer-events: none;">
   </div>
   <a-modal v-model:visible="modalIsShow" :title="modalTitle" @ok="handleOk">
     <div class="modal-container">
@@ -345,7 +344,7 @@
 
 <script setup lang="ts">
   import { ExclamationCircleFilled } from '@ant-design/icons-vue';
-  import { onBeforeMount, ref, watch, onMounted, nextTick, toRaw, reactive, onUnmounted, inject } from 'vue';
+  import { onBeforeMount, ref, watch, onMounted, nextTick, toRaw, reactive, onUnmounted, inject, unref } from 'vue';
   import BarSingle from '../../../../components/chart/BarSingle.vue';
   import GroupMonitorTable from '../comment/GroupMonitorTable.vue';
   import HistoryTable from '../comment/HistoryTable.vue';
@@ -370,7 +369,7 @@
   import { getPopupContainer } from '/@/utils';
   import { getDictItemsByCode } from '/@/utils/dict';
   import { message } from 'ant-design-vue';
-  import { TableAction } from '/@/components/Table';
+   import { useCamera } from '/@/hooks/system/useCamera';
   import { CaretRightOutlined } from '@ant-design/icons-vue';
 
   const globalConfig = inject('globalConfig');
@@ -532,6 +531,8 @@
   const deviceType = ref(selectData.deviceType)
   const headElHeight = ref(0)
 
+  const {getCamera, webRtcServer} = useCamera()
+
   watch(deviceType , (type) => {
     rightColumns.value = getTableHeaderColumns(type + '_monitor_right') as []
     if(rightColumns.value && rightColumns.value.length < 1){
@@ -655,7 +656,7 @@
   };
 
   // 切换检测数据
-  function getSelectRow(id) {
+  async function getSelectRow(id) {
     console.log('选中的设备id------->', id)
 
     if (!id || id == selectData['deviceID']) return;
@@ -696,8 +697,8 @@
         xAxisDataGas.value = xAxisDataGasArr
       }
     })
-    
-    
+
+    await getCamera(id, playerRef.value)
     return;
   };
 
@@ -875,13 +876,15 @@
   });
 
   onMounted(() => {
-    
+    const { query } = unref(currentRoute);
+    if(query['deviceType']) devicekide.value = query['deviceType'] as string
     mountedThree(player1.value).then(async () => {
       await getMonitor(true);
       nextTick(async() => {
         addCssText();        
       });
     });
+    
     document.body.addEventListener('mousedown', addPlayVideo, false);
   });
 
@@ -891,6 +894,11 @@
       clearTimeout(timer);
       timer = undefined;
     }
+    if (webRtcServer.length > 0) {
+      webRtcServer.forEach(item => {
+        item.disconnect()
+      })
+    }
   });
 </script>
 <style scoped lang="less">
@@ -1126,4 +1134,9 @@
   .@{ventSpace}-input {
     width: 150px;
   }
+  :deep(#LivePlayerBox){
+    display: flex;
+    justify-content: end;
+    padding-right: 380px;
+  }
 </style>

+ 1 - 1
src/views/vent/monitorManager/gateMonitor/index.vue

@@ -663,7 +663,7 @@ onUnmounted(() => {
   }
 });
 </script>
-
+ ,
 <style lang="less" scoped>
 @import '/@/design/vent/modal.less';
 .scene-box{

+ 1 - 1
src/views/vent/monitorManager/windowMonitor/dandaoFc.threejs.ts

@@ -123,7 +123,7 @@ class singleWindow {
         text:
           selectData.maxarea && selectData.maxarea !== '-'
             ? selectData.maxarea == 100
-              ? `0~${selectData.maxarea}°%`
+              ? `0~${selectData.maxarea}`
               : `0~${selectData.maxarea}`
             : '-',
         font: 'normal 30px Arial',