diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/QUICK_START.md b/packages/screen/src/views/3DSituationalAwarenessRefactor/QUICK_START.md
deleted file mode 100644
index e18974e..0000000
--- a/packages/screen/src/views/3DSituationalAwarenessRefactor/QUICK_START.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# 🚀 快速开始指南
-
-## ✅ 重构完成清单
-
-- [x] 20 个 Vue 组件(模块化、语义化)
-- [x] 3 个 Composables(状态管理)
-- [x] 119 个图片资源(已复制并更新路径)
-- [x] 公共样式和常量配置
-- [x] 完整的项目文档
-
-**总计:148 个文件,重构 100% 完成!** ✨
-
----
-
-## 🎯 立即使用
-
-### 1. 启动项目
-```bash
-cd bxztApp
-pnpm dev:screen
-```
-
-### 2. 添加路由(如果还未添加)
-在路由配置文件中添加:
-```javascript
-{
- path: '/3d-situational-awareness',
- component: () => import('@/views/3DSituationalAwarenessRefactor/index.vue')
-}
-```
-
-### 3. 访问页面
-浏览器打开:`http://localhost:xxxx/3d-situational-awareness`
-
----
-
-## 📂 核心文件位置
-
-| 文件 | 路径 | 说明 |
-|------|------|------|
-| **主页面** | `index.vue` | 入口文件 |
-| **左侧面板** | `components/LeftPanel/` | 5个组件 |
-| **右侧面板** | `components/RightPanel/` | 5个组件 |
-| **地图区域** | `components/MapViewer/` | 2个组件 |
-| **公共组件** | `components/shared/` | 3个组件 |
-| **状态管理** | `composables/` | 3个JS文件 |
-| **图片资源** | `assets/images/` | 119个PNG |
-
----
-
-## 📚 文档导航
-
-1. **📖 完整项目说明**
- → `README.md`(组件使用、样式规范、开发指南)
-
-2. **📊 重构总结报告**
- → `REFACTORING_SUMMARY.md`(对比分析、最佳实践)
-
-3. **🖼️ 图片资源说明**
- → `assets/images/README.md`(图片使用方式)
-
-4. **🗺️ 图片路径映射**
- → `assets/images/IMAGE_MAPPING.md`(文件名对照表)
-
----
-
-## 🔥 核心改进
-
-| 指标 | 原始代码 | 重构后 |
-|------|----------|---------|
-| 文件数量 | 1个 | 148个 |
-| 单文件行数 | 792行 | <200行 |
-| 命名方式 | `group_1` | `DisasterAnalysis` |
-| 响应式 | 固定像素 | vw/vh/fs |
-| 可维护性 | ❌ 差 | ✅ 优秀 |
-
----
-
-## ⚡ 快速定位问题
-
-### 如果页面不显示
-1. 检查路由配置是否正确
-2. 确认图片路径是否正确
-3. 查看浏览器控制台错误
-
-### 如果图片不显示
-1. 确认图片文件已复制(119个)
-2. 检查图片路径(使用 SketchPng... 格式)
-3. 查看 `assets/images/IMAGE_MAPPING.md`
-
-### 如果样式错误
-1. 确认 `@/styles/mixins.scss` 存在
-2. 检查 vw/vh/fs 函数定义
-3. 查看 `assets/styles/common.scss`
-
----
-
-## 🎨 组件使用示例
-
-```vue
-
-
-
-
-
-
-
-
-
-
-```
-
----
-
-## 📞 需要帮助?
-
-查看详细文档:
-- `README.md` - 完整使用指南
-- `REFACTORING_SUMMARY.md` - 重构详情
-
----
-
-**重构完成!立即启动项目体验全新代码结构!** 🎉
diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/README.md b/packages/screen/src/views/3DSituationalAwarenessRefactor/README.md
deleted file mode 100644
index 6757af5..0000000
--- a/packages/screen/src/views/3DSituationalAwarenessRefactor/README.md
+++ /dev/null
@@ -1,262 +0,0 @@
-# 3D态势感知应急驾驶舱 - 重构版
-
-## 📋 项目概述
-
-这是对从蓝湖导出的 `3DSituationalAwarenessCopy` 页面的完整重构版本,解决了原始代码的可维护性问题。
-
-## ✨ 重构成果
-
-### 改进前(原始代码)
-- ❌ 792 行代码全在一个文件
-- ❌ 使用 `group_1`、`block_1` 等无意义命名
-- ❌ 硬编码像素值,不支持响应式
-- ❌ 深层嵌套的 div 结构
-- ❌ 绝对定位 + margin 混乱布局
-
-### 改进后(重构代码)
-- ✅ 拆分为 20+ 个独立组件
-- ✅ 语义化命名,一目了然
-- ✅ 使用 vw/vh/fs 响应式单位
-- ✅ 清晰的组件层次结构
-- ✅ CSS Grid + Flexbox 现代布局
-- ✅ Vue 3 Composition API + `
diff --git a/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/EmergencyPlanContent.vue b/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/EmergencyPlanContent.vue
index 917003b..adbf06b 100644
--- a/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/EmergencyPlanContent.vue
+++ b/packages/screen/src/views/3DSituationalAwarenessRefactor/components/shared/EmergencyPlanContent.vue
@@ -707,22 +707,24 @@ const handleDeletePlan = (id) => {
:deep(.el-textarea__inner) {
background: #052044 !important;
- border: 1px solid rgba(28, 161, 255, 0.3) !important;
+ border: none !important;
+ box-shadow: 0 0 0 1px rgba(28, 161, 255, 0.3) inset !important;
border-radius: vw(4);
color: var(--text-white);
font-size: fs(13);
font-family: SourceHanSansCN-Regular, sans-serif;
line-height: 1.6;
padding: vh(8) vw(12);
- transition: border-color 0.3s ease;
+ transition: box-shadow 0.3s ease;
&:hover {
- border-color: var(--primary-color) !important;
+ box-shadow: 0 0 0 1px var(--primary-color) inset !important;
}
- &:focus {
- border-color: var(--primary-color) !important;
- box-shadow: none !important;
+ &:focus,
+ &:focus-visible {
+ box-shadow: 0 0 0 1px var(--primary-color) inset !important;
+ outline: none !important;
}
&::placeholder {
@@ -835,22 +837,24 @@ const handleDeletePlan = (id) => {
.follow-up-textarea {
:deep(.el-textarea__inner) {
background: #052044 !important;
- border: 1px solid rgba(28, 161, 255, 0.3) !important;
+ border: none !important;
+ box-shadow: 0 0 0 1px rgba(28, 161, 255, 0.3) inset !important;
border-radius: vw(4);
color: var(--text-white);
font-size: fs(13);
font-family: SourceHanSansCN-Regular, sans-serif;
line-height: 1.8;
padding: vh(10) vw(14);
- transition: border-color 0.3s ease;
+ transition: box-shadow 0.3s ease;
&:hover {
- border-color: var(--primary-color) !important;
+ box-shadow: 0 0 0 1px var(--primary-color) inset !important;
}
- &:focus {
- border-color: var(--primary-color) !important;
- box-shadow: none !important;
+ &:focus,
+ &:focus-visible {
+ box-shadow: 0 0 0 1px var(--primary-color) inset !important;
+ outline: none !important;
}
&::placeholder {
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([]);