From 58fe72f71793855c55fca6baeae7e796866322d6 Mon Sep 17 00:00:00 2001 From: Zzc <1373857752@qq.com> Date: Mon, 24 Nov 2025 13:47:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(screen):=20=E5=9C=A8=E5=9C=B0=E5=9B=BE?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=8F=90=E7=A4=BA=E4=B8=AD=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为支持视频的实体(如应急中心、储备中心和预设点)在MapTooltip组件中添加视频图标按钮。包含VideoModal集成,用于显示带控制功能的视频流。 --- .../assets/images/media.png | Bin 0 -> 863 bytes .../components/shared/MapTooltip.vue | 85 +++++++++++++++++- .../3DSituationalAwarenessRefactor/index.vue | 68 +++++++++++++- 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/media.png diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/media.png b/packages/screen/src/views/3DSituationalAwarenessRefactor/assets/images/media.png new file mode 100644 index 0000000000000000000000000000000000000000..3095a3291acc79eeef5cb0485674191e45ccd50a GIT binary patch literal 863 zcmV-l1EBngP)6f_=~f z#{#a6nQI@TV?iJ=`fC(z?Bx{OmqG#jO5;*y4|_$y{DMZ!|D%#dQoj_l zhrOcfWP$hfDA>doPa#h(?v)(i8Tq>Dt3y(RH%m6OmcasNGHo=l(I z2Y5xqyC5!Oet$E;oPc#czR#2MiTD6tZuYQO6i*KDl*oL@voi$GL4Otc$Q^>8a00sE zC6t>z>=ni10SbkJQ~ATf38Q4<#Une(_2DWUA?KqPSJBk|5qd>M@c_|POUn)XGMFq= z`+8D5H2{ATT!Hrnf~(7{bx)D% zOF@fe)+!EQDI3SY-}!z!Jj&(7eOEK_$-SA002ovPDHLkV1k#io5TPB literal 0 HcmV?d00001 diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/MapTooltip.vue b/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/MapTooltip.vue index ca7ff3d..f3d2427 100644 --- a/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/MapTooltip.vue +++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/MapTooltip.vue @@ -65,6 +65,20 @@ > {{ title }} + + @@ -197,6 +211,30 @@ const props = defineProps({ closable: { type: Boolean, default: true + }, + + /** + * 是否在标题右侧显示视频图标 + */ + showVideoIcon: { + type: Boolean, + default: false + }, + + /** + * 视频图标的图片路径 + */ + videoIconSrc: { + type: String, + default: '' + }, + + /** + * 视频图标的无障碍标签 + */ + videoIconAriaLabel: { + type: String, + default: '打开视频监控' } }) @@ -211,7 +249,11 @@ const emit = defineEmits([ /** * 支持 v-model:visible 双向绑定 */ - 'update:visible' + 'update:visible', + /** + * 用户点击视频图标时触发 + */ + 'video-icon-click' ]) /** @@ -354,6 +396,47 @@ const handleClose = () => { line-height: 1.4; } +/** + * 视频图标按钮 + * 显示在标题右侧,用于打开视频监控 + */ +.map-tooltip__video-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: vw(24); + height: vw(24); + padding: 0; + border: none; + background: transparent; + cursor: pointer; + flex-shrink: 0; + transition: all 0.3s ease; + + &:hover { + transform: scale(1.15); + filter: brightness(1.2); + } + + &:active { + transform: scale(1.05); + } + + &:focus-visible { + outline: 2px solid var(--primary-color); + outline-offset: 2px; + border-radius: 2px; + } +} + +.map-tooltip__video-icon { + width: 100%; + height: 100%; + object-fit: contain; + display: block; + pointer-events: none; +} + /** * 关闭按钮 * 使用纯 CSS 实现 X 图标,避免额外的图片资源 diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/index.vue b/packages/screen/src/views/3DSituationalAwarenessRefactor/index.vue index 13a8ed7..6a57529 100644 --- a/packages/screen/src/views/3DSituationalAwarenessRefactor/index.vue +++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/index.vue @@ -116,6 +116,9 @@ :title="mapTooltip.title" :icon="mapTooltip.icon" :z-index="mapTooltip.zIndex" + :show-video-icon="mapTooltip.data && mapTooltip.data.supportVideo" + :video-icon-src="mediaIcon" + @video-icon-click="handleVideoIconClick" @close="handleMapTooltipClose" > @@ -168,6 +171,14 @@ @close="showCenterDetail = false" /> + + + { let title = ''; const fields = []; const actions = []; + let supportVideo = false; + let videoTitle = ''; + const videoSrc = 'http://222.212.85.86:9000/300bdf2b-a150-406e-be63-d28bd29b409f/demo/ylzg/单兵视角.mp4'; if (type === 'soldier') { // 应急人员 @@ -510,6 +526,8 @@ const showMarkerTooltip = (viewer, entity, screenPosition, icon) => { { label: '隶属单位', value: '交通公路部门' }, { label: '位置信息', value: `目前为止距离现场${distance}公里` } ); + supportVideo = true; + videoTitle = '应急中心'; } else { // 其他养护站显示 tooltip title = '养护站'; @@ -525,6 +543,8 @@ const showMarkerTooltip = (viewer, entity, screenPosition, icon) => { { label: '名称', value: properties.name?.getValue() || '-' }, { label: '位置信息', value: properties.location?.getValue() || '-' } ); + supportVideo = true; + videoTitle = '储备中心'; } else if (type === 'presetPoint') { // 预置点 title = '预置点'; @@ -532,6 +552,8 @@ const showMarkerTooltip = (viewer, entity, screenPosition, icon) => { { label: '名称', value: properties.name?.getValue() || '-' }, { label: '位置信息', value: properties.location?.getValue() || '-' } ); + supportVideo = true; + videoTitle = '预置点'; } // 显示 Tooltip,使用实体的屏幕坐标 @@ -540,7 +562,13 @@ const showMarkerTooltip = (viewer, entity, screenPosition, icon) => { y: canvasPosition.y, title, icon, - data: { fields, actions: actions.length > 0 ? actions : undefined } + data: { + fields, + actions: actions.length > 0 ? actions : undefined, + supportVideo, + videoTitle, + videoSrc + } }); // 保存当前实体,用于相机移动时更新位置 @@ -989,6 +1017,7 @@ const handleMapToolChange = async ({ tool, active }) => { const showPersonnelDetail = ref(false); const showCenterDetail = ref(false); const showStretchableModal = ref(false); +const showVideoModal = ref(false); // 选中的数据 const selectedPersonnel = ref({ @@ -1007,6 +1036,16 @@ const selectedCenter = ref({ image: null, }); +const selectedVideoMonitor = ref({ + id: '', + title: '', + videoSrc: '', + dateRange: '', + hasMegaphone: false, + hasAudio: true, + hasDirectionControl: false +}); + // 返回驾驶舱 const handleBack = () => { console.log("返回驾驶舱"); @@ -1080,6 +1119,33 @@ const handleMapTooltipClose = () => { mapTooltip.value.visible = false; }; +/** + * 处理视频图标点击事件 + * 打开视频弹窗并设置视频源 + */ +const handleVideoIconClick = () => { + const { data } = mapTooltip.value; + if (data && data.supportVideo) { + selectedVideoMonitor.value = { + id: Date.now().toString(), + title: data.videoTitle || '视频监控', + videoSrc: data.videoSrc || '', + dateRange: new Date().toLocaleDateString(), + hasMegaphone: false, + hasAudio: true, + hasDirectionControl: false + }; + showVideoModal.value = true; + } +}; + +/** + * 处理视频弹窗关闭事件 + */ +const handleVideoModalClose = () => { + showVideoModal.value = false; +}; + // 路径线实体引用 const pathLineEntities = ref([]);