|
|
@@ -1,100 +1,59 @@
|
|
|
<template>
|
|
|
<div class="camera-modal">
|
|
|
- <!-- 遍历每个设备组 -->
|
|
|
- <div v-for="(group, groupIndex) in props.data" :key="groupIndex" class="sensor-group">
|
|
|
- <div class="group-title">{{ group.strname }}</div>
|
|
|
- <div class="camera-area">
|
|
|
- <div v-for="camera in group.cameras || []" :key="camera.id" :ref="(el) => setPlayerRef(el, group.deviceID)" class="single-camera-container">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="camrea-area">
|
|
|
+ <!-- 完全沿用你成熟的播放器容器 -->
|
|
|
+ <div v-if="renderPlayer" ref="playerRef" style="display: flex; width: 100%; height: 100%; overflow-y: auto; pointer-events: none"></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { onMounted, ref, reactive, computed, onBeforeUnmount } from 'vue';
|
|
|
-import { useCamera } from '/@/hooks/system/useCamera';
|
|
|
-const props = defineProps<{
|
|
|
- config: Array<{
|
|
|
- title: string;
|
|
|
- contents: Array<{ code: string }>;
|
|
|
- }>;
|
|
|
- data: any[];
|
|
|
-}>();
|
|
|
-const renderPlayer = ref(true);
|
|
|
-const { getCamera, removeCamera } = useCamera();
|
|
|
-const deviceDomMap = reactive<Record<string, HTMLElement>>({});
|
|
|
-const setPlayerRef = (el: HTMLElement | null, deviceId: string) => {
|
|
|
- if (el) {
|
|
|
- deviceDomMap[deviceId] = el;
|
|
|
- } else {
|
|
|
- delete deviceDomMap[deviceId];
|
|
|
- }
|
|
|
-};
|
|
|
-const allVideos = computed(() => {
|
|
|
- return (
|
|
|
- props.data?.flatMap((item) => {
|
|
|
- const cameras = item.cameras || [];
|
|
|
- return [item, ...cameras];
|
|
|
- }) || []
|
|
|
- );
|
|
|
+import { onMounted, ref, onBeforeUnmount } from 'vue';
|
|
|
+// 用你成熟的摄像头hooks
|
|
|
+import { useCamera } from '/@/hooks/system/useCameraPianation';
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ data: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
-onMounted(async () => {
|
|
|
- const videos = allVideos.value;
|
|
|
- for (const video of videos) {
|
|
|
- if (video.deviceID) {
|
|
|
- const targetDom = deviceDomMap[video.deviceID];
|
|
|
- if (targetDom) {
|
|
|
- await getCamera(video.deviceID, targetDom, renderPlayer);
|
|
|
- } else {
|
|
|
- console.warn(`未找到设备 ${video.deviceID} 的 DOM 容器`);
|
|
|
- }
|
|
|
+const { getCamera, removeCamera } = useCamera();
|
|
|
+const playerRef = ref();
|
|
|
+const renderPlayer = ref(true);
|
|
|
+
|
|
|
+// 提取所有摄像头
|
|
|
+const allCameras = () => {
|
|
|
+ const list = [];
|
|
|
+ props.data.forEach((device) => {
|
|
|
+ if (device.cameras && device.cameras.length > 0) {
|
|
|
+ device.cameras.forEach((item) => {
|
|
|
+ list.push({
|
|
|
+ ...item,
|
|
|
+ deviceID: device.deviceID, // 携带设备ID
|
|
|
+ });
|
|
|
+ });
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
+ return list;
|
|
|
+};
|
|
|
+onMounted(async () => {
|
|
|
+ const cameras = allCameras();
|
|
|
+ await getCamera('', playerRef, renderPlayer, '', cameras);
|
|
|
});
|
|
|
|
|
|
+// 销毁
|
|
|
onBeforeUnmount(() => {
|
|
|
- removeCamera(Object.values(deviceDomMap));
|
|
|
+ removeCamera(playerRef);
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
.camera-modal {
|
|
|
width: 100%;
|
|
|
- height: 95%;
|
|
|
- padding: 5px 10px;
|
|
|
- box-sizing: border-box; // 防止 padding 撑破容器
|
|
|
- .sensor-group {
|
|
|
- background: url('@/assets/images/beltFire/fireMonitor/2-1.png') no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- padding: 10px;
|
|
|
- height: 580px;
|
|
|
- margin-bottom: 10px; // 增加组间距
|
|
|
- }
|
|
|
- .group-title {
|
|
|
- background: url('@/assets/images/beltFire/fireMonitor/2-2.png') no-repeat;
|
|
|
- background-size: 45% 100%;
|
|
|
- color: #fff;
|
|
|
- font-size: 12px;
|
|
|
- font-weight: bold;
|
|
|
- font-style: italic;
|
|
|
- margin-bottom: 8px;
|
|
|
- padding-bottom: 5px;
|
|
|
- padding-left: 10px;
|
|
|
- }
|
|
|
- .camera-area {
|
|
|
- width: 100%;
|
|
|
- height: calc(100% - 40px); // 减去标题高度
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap; // 允许换行
|
|
|
- align-content: flex-start;
|
|
|
- overflow-y: auto;
|
|
|
- }
|
|
|
- .single-camera-container {
|
|
|
- // 这里可以根据需要调整大小,或者让内部的播放器自适应
|
|
|
- flex: 0 0 auto;
|
|
|
- width: 100%; // 或者根据需求设置为 50% 等
|
|
|
+ .camrea-area {
|
|
|
+ width: 90%;
|
|
|
height: 100%;
|
|
|
}
|
|
|
}
|
|
|
@@ -105,19 +64,16 @@ onBeforeUnmount(() => {
|
|
|
justify-content: flex-start;
|
|
|
flex-wrap: wrap;
|
|
|
pointer-events: none;
|
|
|
-
|
|
|
.liveVideo {
|
|
|
- width: 462px !important;
|
|
|
+ width: 430px !important;
|
|
|
height: 276px !important;
|
|
|
padding: 15px !important;
|
|
|
align-self: auto !important;
|
|
|
margin: 10px 8px !important;
|
|
|
background-size: 100% 100% !important;
|
|
|
}
|
|
|
-
|
|
|
.video-parent {
|
|
|
pointer-events: auto !important;
|
|
|
- align-self: auto !important;
|
|
|
}
|
|
|
}
|
|
|
</style>
|