فهرست منبع

Merge branch 'qhse_fix' of shuzhihua/pms-iot-vue into master

yanghao 12 ساعت پیش
والد
کامیت
fe00225173
3فایلهای تغییر یافته به همراه182 افزوده شده و 43 حذف شده
  1. 4 5
      src/components/UserSelectForm/index.vue
  2. 18 20
      src/views/pms/video_center/sip/index.vue
  3. 160 18
      src/views/pms/video_center/sip/splitview.vue

+ 4 - 5
src/components/UserSelectForm/index.vue

@@ -8,7 +8,6 @@
             :data="deptTree"
             :expand-on-click-node="false"
             :props="defaultProps"
-            default-expand-all
             highlight-current
             node-key="id"
             @node-click="handleNodeClick"
@@ -42,8 +41,8 @@
 import { defaultProps, handleTree } from '@/utils/tree'
 import * as DeptApi from '@/api/system/dept'
 import * as UserApi from '@/api/system/user'
-import {companyLevelChildrenDepts} from "@/api/system/dept";
-import {companyDeptsEmployee} from "@/api/system/user";
+import { companyLevelChildrenDepts } from '@/api/system/dept'
+import { companyDeptsEmployee } from '@/api/system/user'
 
 defineOptions({ name: 'UserSelectForm' })
 const emit = defineEmits<{
@@ -86,10 +85,10 @@ const open = async (id: number, selectedList?: any[]) => {
   deptList.value = deptData // 保存扁平结构的部门数据
   deptTree.value = handleTree(deptData) // 转换成树形结构
   // userList.value = await UserApi.getSimpleUserList()
-  const ids = deptData.map(item => item.id)
+  const ids = deptData.map((item) => item.id)
   const params = {
     deptIds: ids
-  };
+  }
   debugger
   userList.value = await UserApi.companyDeptsEmployee(params)
 

+ 18 - 20
src/views/pms/video_center/sip/index.vue

@@ -38,7 +38,7 @@
         </el-form-item>
         <el-form-item>
           <el-button type="primary" :icon="Search" size="default" @click="handleQuery"
-            >搜</el-button
+            >搜</el-button
           >
           <el-button :icon="Refresh" size="default" @click="resetQuery">重置</el-button>
         </el-form-item>
@@ -49,14 +49,7 @@
         <el-button type="primary" plain :icon="Plus" size="small" @click="handleAdd">
           添加
         </el-button>
-        <el-button
-          type="danger"
-          plain
-          :icon="Delete"
-          size="small"
-          :disabled="multiple || isGeneralUser"
-          @click="handleDelete"
-        >
+        <el-button type="danger" plain :icon="Delete" size="small" @click="handleDelete">
           删除
         </el-button>
       </div>
@@ -65,9 +58,10 @@
         :data="sipidList"
         @selection-change="handleSelectionChange"
         @cell-dblclick="celldblclick"
+        :header-cell-style="{ background: '#f5f5f5' }"
       >
         <el-table-column type="selection" :selectable="selectable" width="55" align="center" />
-        <el-table-column label="设备编号" align="center" prop="deviceSipId">
+        <el-table-column label="设备编号" align="center" prop="deviceSipId" min-width="120">
           <template #default="scope">
             <el-link
               :underline="false"
@@ -77,7 +71,12 @@
             >
           </template>
         </el-table-column>
-        <el-table-column :label="t('sip.index998533-2')" align="center" prop="channelSipId" />
+        <el-table-column
+          :label="t('sip.index998533-2')"
+          align="center"
+          prop="channelSipId"
+          min-width="120"
+        />
         <el-table-column :label="t('sip.index998533-4')" align="center" prop="status" width="80">
           <template #default="scope">
             <dict-tag
@@ -139,6 +138,7 @@
             v-model="createForm.city"
             @change="changeProvince"
             :props="{ checkStrictly: true }"
+            style="width: 100%"
           />
         </el-form-item>
         <el-form-item :label="t('sip.index998533-9')" prop="deviceType">
@@ -178,7 +178,7 @@
             v-model="createForm.createNum"
             :max="10"
             :placeholder="t('sip.index998533-19')"
-            style="width: 330px"
+            style="width: 100%"
           />
         </el-form-item>
       </el-form>
@@ -190,6 +190,7 @@
       </template>
     </el-dialog>
     <el-dialog :title="title" v-model="bindingOpen" width="450px" append-to-body>
+      <div class="mt-2"></div>
       <el-form :model="form" ref="formRef">
         <el-form-item :label="t('sip.index998533-22')" prop="deviceId">
           <el-select
@@ -208,7 +209,7 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item :label="t('sip.index998533-24')" prop="sceneId">
+        <!-- <el-form-item :label="t('sip.index998533-24')" prop="sceneId">
           <el-select
             style="width: 210px"
             v-model="form.reSceneModelId"
@@ -223,7 +224,7 @@
               :value="item.sceneModelId"
             />
           </el-select>
-        </el-form-item>
+        </el-form-item> -->
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -591,11 +592,8 @@ const getDeviceList = () => {
     pageSize: 9999
   }
   listDeviceShort(params).then((res) => {
-    if (res.code === 200) {
-      deviceList.value = res.rows
-    } else {
-      // $message.error(res.msg)
-    }
+    console.log('*******************************', res)
+    deviceList.value = res
   })
 }
 
@@ -737,7 +735,7 @@ onMounted(() => {
   //     isGeneralUser.value = false
   // }
   getList()
-  // getDeviceList()
+  getDeviceList()
   // getSceneListDatas()
 })
 </script>

+ 160 - 18
src/views/pms/video_center/sip/splitview.vue

@@ -3,18 +3,23 @@
     <el-card
       id="devicePosition"
       shadow="never"
-      style="height: calc(100% - 40px); border: 0"
+      style="height: calc(100%); border: 0"
       :body-style="{ padding: '0px' }"
       class="border-none"
     >
       <el-container style="height: 100%">
-        <el-aside width="250px" style="background-color: #ffffff">
+        <!-- 左侧设备列表 -->
+        <el-aside width="250px" style="background-color: #ffffff" :class="{ hidden: isFullscreen }">
           <DeviceTree :click-event="clickEvent" />
         </el-aside>
-        <el-main style="padding: 0">
+
+        <!-- 主体内容 -->
+        <div style="padding: 0" class="el-main">
+          <!-- 上方分屏按钮 -->
           <div
             height="5vh"
             style="text-align: left; font-size: 17px; line-height: 5vh; margin-bottom: 10px"
+            :class="{ hidden: isFullscreen }"
           >
             {{ t('sip.splitview998531-1') }}
             <el-button
@@ -50,9 +55,17 @@
             >
               {{ t('sip.splitview998531-4') }}
             </el-button>
+
+            <el-button @click="toggleFullscreen" :type="isFullscreen ? 'danger' : 'primary'">
+              {{ isFullscreen ? '退出全屏' : '全屏' }}
+            </el-button>
           </div>
-          <div style="height: 85vh; display: flex; flex-wrap: wrap">
-            <!-- 渲染所有分屏数量的播放框 -->
+
+          <!-- 分屏播放区域 -->
+          <div
+            style="height: 85vh; display: flex; flex-wrap: wrap"
+            :class="{ 'fullscreen-layout': isFullscreen }"
+          >
             <div
               v-for="i in spilt"
               :key="i"
@@ -61,14 +74,12 @@
               :class="{ redborder: playerIdx == i - 1 }"
               @click="playerIdx = i - 1"
             >
-              <!-- 显示序号,如果该位置没有视频或不在可用通道范围内 -->
               <div
                 v-if="!videoUrl[i - 1] || i - 1 >= availableChannels.length"
                 style="color: #ffffff; font-size: 30px; font-weight: bold"
               >
                 {{ i }}
               </div>
-              <!-- 只有当有视频URL时才渲染播放器 -->
               <player
                 v-if="videoUrl[i - 1]"
                 :ref="(el) => setPlayerRef(el, i - 1)"
@@ -87,7 +98,7 @@
               />
             </div>
           </div>
-        </el-main>
+        </div>
       </el-container>
     </el-card>
   </div>
@@ -132,14 +143,38 @@ const setPlayerRef = (el, index) => {
 
 // 计算属性 - 直播样式
 const liveStyle = computed(() => {
-  let style = { width: '81%', height: '99%' }
-  switch (spilt.value) {
-    case 4:
-      style = { width: '40%', height: '49%' }
-      break
-    case 9:
-      style = { width: '27%', height: '32%' }
-      break
+  let style = {}
+  // switch (spilt.value) {
+  //   case 4:
+  //     style = { width: '40%', height: '49%' }
+  //     break
+  //   case 9:
+  //     style = { width: '27%', height: '32%' }
+  //     break
+  // }
+
+  if (spilt.value === 1) {
+    if (isFullscreen.value) {
+      style = { width: '100%', height: '100%' }
+    } else {
+      style = { width: '81%', height: '99%', 'margin-right': '5px' }
+    }
+  }
+
+  if (spilt.value === 4) {
+    if (isFullscreen.value) {
+      style = { width: '50%', height: '50%' }
+    } else {
+      style = { width: '40%', height: '49%', 'margin-right': '5px' }
+    }
+  }
+
+  if (spilt.value === 9) {
+    if (isFullscreen.value) {
+      style = { width: '33.3%', height: '33.3%' }
+    } else {
+      style = { width: '27%', height: '32%', 'margin-right': '5px' }
+    }
   }
 
   nextTick(() => {
@@ -280,13 +315,76 @@ watch(
   }
 )
 
+// 全屏状态
+const isFullscreen = ref(false)
+
+// 切换全屏
+const toggleFullscreen = () => {
+  const container = document.getElementById('devicePosition') // 获取全屏容器
+  if (!container) return
+
+  if (!isFullscreen.value) {
+    // 进入全屏
+    if (container.requestFullscreen) {
+      container.requestFullscreen()
+    } else if (container.webkitRequestFullscreen) {
+      container.webkitRequestFullscreen() // Safari
+    } else if (container.mozRequestFullScreen) {
+      container.mozRequestFullScreen() // Firefox
+    } else if (container.msRequestFullscreen) {
+      container.msRequestFullscreen() // IE/Edge
+    }
+  } else {
+    // 退出全屏
+    if (document.exitFullscreen) {
+      document.exitFullscreen()
+    } else if (document.webkitExitFullscreen) {
+      document.webkitExitFullscreen() // Safari
+    } else if (document.mozCancelFullScreen) {
+      document.mozCancelFullScreen() // Firefox
+    } else if (document.msExitFullscreen) {
+      document.msExitFullscreen() // IE/Edge
+    }
+  }
+}
+
+// 监听全屏状态变化
+const handleFullscreenChange = () => {
+  isFullscreen.value = !!(
+    document.fullscreenElement ||
+    document.webkitFullscreenElement ||
+    document.mozFullScreenElement ||
+    document.msFullscreenElement
+  )
+
+  // 动态调整主内容区域宽度
+  const mainContent = document.querySelector('.el-main')
+  if (mainContent) {
+    if (isFullscreen.value) {
+      mainContent.style.width = '100vw'
+      mainContent.style.marginLeft = '0'
+    } else {
+      mainContent.style.width = ''
+      mainContent.style.marginLeft = ''
+    }
+  }
+}
+
 // 生命周期钩子
 onMounted(() => {
   checkPlayByParam()
+  document.addEventListener('fullscreenchange', handleFullscreenChange)
+  document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
+  document.addEventListener('mozfullscreenchange', handleFullscreenChange)
+  document.addEventListener('MSFullscreenChange', handleFullscreenChange)
 })
 
 onUnmounted(() => {
   clearTimeout(updateLooper.value)
+  document.removeEventListener('fullscreenchange', handleFullscreenChange)
+  document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
+  document.removeEventListener('mozfullscreenchange', handleFullscreenChange)
+  document.removeEventListener('MSFullscreenChange', handleFullscreenChange)
 })
 
 // 销毁事件
@@ -535,9 +633,9 @@ const clear = (idx) => {
   display: flex;
   align-items: center;
   justify-content: center;
-  margin-right: 10px;
+  /* margin-right: 10px; */
   position: relative;
-  border-radius: 5px;
+  /* border-radius: 5px; */
 }
 
 .empty-box {
@@ -551,4 +649,48 @@ const clear = (idx) => {
   top: 0px;
   height: 100% !important;
 }
+
+.hidden {
+  display: none !important;
+}
+
+/* 全屏时隐藏滚动条 */
+:-webkit-full-screen {
+  overflow: hidden;
+}
+
+:-moz-full-screen {
+  overflow: hidden;
+}
+
+:-ms-fullscreen {
+  overflow: hidden;
+}
+
+/* :fullscreen {
+  height: 100vh !important;
+  width: 100vw !important;
+  margin: 0 !important;
+
+  position: fixed !important;
+  top: 0 !important;
+  left: 0 !important;
+  overflow: hidden !important;
+  max-width: 100vw !important;
+  max-height: 100vh !important;
+} */
+
+.fullscreen-layout {
+  height: 100vh !important;
+  width: 100vw !important;
+  margin: 0 !important;
+  padding: 0 !important;
+  position: fixed !important;
+  top: 0 !important;
+  left: 0 !important;
+  right: 0 !important;
+  overflow: hidden !important;
+  max-width: 100vw !important;
+  max-height: 100vh !important;
+}
 </style>