From 9f94393090700d72c14017f95b0bbfa7fac9b90c Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Mon, 12 Jan 2026 15:17:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/projectSelect/index.vue | 32 ++-- src/static/map.html | 244 +++++++++++++++++++----------- 2 files changed, 170 insertions(+), 106 deletions(-) diff --git a/src/pages/projectSelect/index.vue b/src/pages/projectSelect/index.vue index 92a1c4c..341aa2c 100644 --- a/src/pages/projectSelect/index.vue +++ b/src/pages/projectSelect/index.vue @@ -1,7 +1,7 @@ @@ -24,13 +24,12 @@ const getProjectList = async () => { projectList.value = res || [] } +// 处理 web-view 加载完成事件 +const handleWebViewLoad = (event) => { + // 当页面重新加载时,HTML 中的代码会自动检测 URL 参数并发送消息 +} + const handleWebViewMessage = (event) => { - console.log('=== 收到 web-view 消息 ==='); - console.log('完整事件对象:', event); - console.log('event.detail:', event.detail); - console.log('event.detail.data:', event.detail.data); - console.log('event.detail.data 类型:', Array.isArray(event.detail.data) ? '数组' : typeof event.detail.data); - // 尝试多种数据格式 let action, projectInfo; @@ -39,13 +38,11 @@ const handleWebViewMessage = (event) => { if (event.detail.data.action) { action = event.detail.data.action; projectInfo = event.detail.data.projectInfo; - console.log('使用对象格式解析'); } // 格式2: event.detail.data 是数组 else if (Array.isArray(event.detail.data) && event.detail.data.length > 0) { action = event.detail.data[0]?.action; projectInfo = event.detail.data[0]?.projectInfo; - console.log('使用数组格式解析'); } } @@ -54,24 +51,25 @@ const handleWebViewMessage = (event) => { if (event.detail.action) { action = event.detail.action; projectInfo = event.detail.projectInfo; - console.log('使用直接格式解析'); } } - console.log('解析后的 action:', action); - console.log('解析后的 projectInfo:', projectInfo); + // 格式4: 安卓环境下可能的数据格式 + if (!action && event.detail && typeof event.detail === 'object') { + if (event.detail.action) { + action = event.detail.action; + projectInfo = event.detail.projectInfo; + } + } if (!action) { console.warn('无法解析 action,消息格式可能不正确'); - console.warn('请检查 event.detail 的结构'); return; } if (action === 'modelPreview') { - console.log('收到模型预览请求,projectId:', projectInfo?.proId); // 模型预览逻辑 getProjectModelListApi({ projectId: projectInfo.proId }).then((res) => { - console.log('获取模型列表成功:', res); if (res?.data?.length > 0) { // 使用 URL 参数方式传递数据(最可靠的方式) const modelListJson = JSON.stringify(res.data); @@ -88,8 +86,6 @@ const handleWebViewMessage = (event) => { const newUrl = `/static/map.html?projectInfo=${projectInfoParam}&modelList=${modelListParam}&clickedProject=${clickedProjectParam}&action=showPreview&t=${timestamp}`; - console.log('准备更新 webViewUrl,URL 长度:', newUrl.length); - // 强制重新渲染 web-view webViewKey.value += 1; // 先清空,再设置新值,确保触发更新 @@ -97,10 +93,8 @@ const handleWebViewMessage = (event) => { setTimeout(() => { webViewUrl.value = newUrl; - console.log('webViewUrl 已更新'); }, 100); } else { - console.warn('该工程暂无模型数据'); uni.$u.toast('该工程暂无模型数据'); } }).catch((err) => { diff --git a/src/static/map.html b/src/static/map.html index 7131578..2e8835c 100644 --- a/src/static/map.html +++ b/src/static/map.html @@ -32,22 +32,29 @@ height: 100%; z-index: 1000; display: flex; - background: rgba(0, 0, 0, 0.3); + pointer-events: none; /* 允许点击穿透到地图 */ + align-items: flex-start; /* 顶部对齐 */ } .model-preview-tree { - width: 300px; - height: 100%; - background: #fff; - border-right: 1px solid #e0e0e0; + width: 200px; + height: auto; + max-height: 80%; + margin-top: 2%; + margin-left: 2%; + background: rgba(30, 30, 30, 0.55); + border-right: 1px solid rgba(51, 51, 51, 0.5); + border-radius: 8px; overflow-y: auto; padding: 20px; + pointer-events: auto; /* 列表区域可以交互 */ + box-shadow: 2px 0 8px rgba(0, 0, 0, 0.3); } .tree-title { font-size: 18px; font-weight: bold; - color: #333; + color: #fff; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 2px solid #002db6; @@ -67,7 +74,7 @@ } .tree-node-item:hover { - background-color: #f5f5f5; + background-color: #323232; } .tree-node-checkbox { @@ -80,7 +87,7 @@ .tree-node-label { flex: 1; font-size: 14px; - color: #333; + color: #fff; user-select: none; } @@ -90,16 +97,17 @@ right: 20px; width: 40px; height: 40px; - background: #fff; - border: 1px solid #ddd; + background: rgba(255, 255, 255, 0.9); + border: 1px solid rgba(221, 221, 221, 0.5); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); transition: all 0.2s; z-index: 1001; + pointer-events: auto; /* 关闭按钮可以点击 */ } .model-preview-close:hover { @@ -253,7 +261,6 @@ if (clickedProjectParam) { try { currentClickedProject = JSON.parse(decodeURIComponent(clickedProjectParam)); - console.log('保存点击的项目信息:', currentClickedProject); } catch (e) { console.error('解析点击项目信息失败:', e); } @@ -262,23 +269,51 @@ // 先初始化地图 initMap(projectInfo) - // 如果 URL 中有模型预览请求,在页面加载完成后显示 + // 如果 URL 中有模型预览请求(通过 URL 参数触发的情况) + if (actionParam === 'modelPreview' && clickedProjectParam) { + // 通过 postMessage 通知 Vue 组件获取模型列表 + const triggerModelPreview = () => { + try { + const projectInfo = JSON.parse(decodeURIComponent(clickedProjectParam)); + + // 尝试多种方式发送消息 + const messageData = { + data: { + action: 'modelPreview', + projectInfo: projectInfo + } + }; + + // 方案1: uni.postMessage + if (typeof uni !== 'undefined' && typeof uni.postMessage === 'function') { + uni.postMessage(messageData); + return; + } + + // 方案2: window.parent.postMessage + if (window.parent && window.parent !== window) { + window.parent.postMessage(messageData, '*'); + return; + } + } catch (e) { + console.error('触发模型预览失败:', e); + } + }; + + // 等待 UniAppJSBridgeReady 后再触发 + setTimeout(triggerModelPreview, 500); + } + + // 如果 URL 中有模型预览请求(已有模型列表的情况),在页面加载完成后显示 if (actionParam === 'showPreview' && modelListParam) { - console.log('检测到模型预览请求'); try { const models = JSON.parse(decodeURIComponent(modelListParam)); - console.log('从 URL 参数获取模型列表,数量:', models.length); // 定义一个函数来显示预览 const showPreviewWhenReady = () => { if (map && typeof window.showModelPreview === 'function') { - console.log('地图和函数都已准备好,显示预览'); window.showModelPreview(models, currentClickedProject); } else { - console.log('等待地图和函数准备...', { - map: !!map, - showModelPreview: typeof window.showModelPreview - }); setTimeout(showPreviewWhenReady, 200); } }; @@ -373,7 +408,12 @@ setTimeout(() => { const menuContainer = document.querySelector('.action-menu'); if (menuContainer) { - menuContainer.addEventListener('click', function(e) { + // 处理点击和触摸事件(兼容安卓) + const handleAction = function(e) { + // 阻止默认行为和事件冒泡 + e.preventDefault(); + e.stopPropagation(); + const target = e.target.closest('.action-menu-item'); if (!target) return; @@ -382,53 +422,55 @@ if (action === 'survey') { // 勘察 - 原来的逻辑 - console.log('发送勘察消息:', projectInfo); + const surveyMessage = { + data: { + action: 'navigateToProject', + projectInfo: projectInfo + } + }; + // 尝试多种方式发送消息 try { - uni.postMessage({ - data: { - action: 'navigateToProject', - projectInfo: projectInfo - } - }); - console.log('勘察消息已发送'); + if (typeof uni !== 'undefined' && typeof uni.postMessage === 'function') { + uni.postMessage(surveyMessage); + } else if (window.parent && window.parent !== window) { + window.parent.postMessage(surveyMessage, '*'); + } } catch (error) { console.error('发送勘察消息失败:', error); } } else if (action === 'preview') { // 模型预览 - console.log('准备发送模型预览消息:---', projectInfo); - console.log(uni.postMessage,'uni.postMessage') - console.log('uni 对象:', typeof uni !== 'undefined' ? uni : '未定义'); - console.log('uni.postMessage:', typeof uni !== 'undefined' && typeof uni.postMessage === 'function' ? '存在' : '不存在'); - - // 确保 uni 对象已加载 - if (typeof uni === 'undefined' || typeof uni.postMessage !== 'function') { - console.error('uni.postMessage 不可用,等待 UniAppJSBridgeReady...'); - // 等待 uni 对象加载 - setTimeout(() => { - if (typeof uni !== 'undefined' && typeof uni.postMessage === 'function') { - sendModelPreviewMessage(projectInfo); - } else { - console.error('uni.postMessage 仍然不可用'); - } - }, 100); - } else { - sendModelPreviewMessage(projectInfo); - } + sendModelPreviewMessage(projectInfo); } + }; + + // 同时监听 click 和 touchstart 事件(安卓兼容) + menuContainer.addEventListener('click', handleAction); + menuContainer.addEventListener('touchend', function(e) { + // 触摸事件需要立即处理,避免延迟 + handleAction(e); }); + + // 防止触摸时触发点击(避免重复触发) + let touchStartTime = 0; + menuContainer.addEventListener('touchstart', function(e) { + touchStartTime = Date.now(); + }); + + menuContainer.addEventListener('click', function(e) { + // 如果刚刚有触摸事件,忽略点击事件(避免重复) + if (Date.now() - touchStartTime < 300) { + e.preventDefault(); + e.stopPropagation(); + } + }, true); } }, 200); } // 发送模型预览消息的辅助函数 function sendModelPreviewMessage(projectInfo) { - console.log('=== 开始发送模型预览消息 ==='); - console.log('projectInfo:', projectInfo); - console.log('uni 对象类型:', typeof uni); - console.log('uni.postMessage 类型:', typeof (uni && uni.postMessage)); - // 根据 uni-app 文档,使用 data 对象格式(不是数组) const messageData = { data: { @@ -437,26 +479,68 @@ } }; - console.log('准备发送的消息数据:', messageData); - + // 方案1: 尝试使用 uni.postMessage(iOS 和部分安卓) + let messageSent = false; try { - if (typeof uni === 'undefined') { - console.error('uni 对象未定义!'); - return; + if (typeof uni !== 'undefined' && typeof uni.postMessage === 'function') { + uni.postMessage(messageData); + messageSent = true; } - - if (typeof uni.postMessage !== 'function') { - console.error('uni.postMessage 不是函数!'); - console.log('uni 对象内容:', Object.keys(uni || {})); - return; - } - - uni.postMessage(messageData); - console.log('✓ 模型预览消息已通过 uni.postMessage 发送'); } catch (error) { - console.error('✗ 发送消息失败:', error); - console.error('错误详情:', error.message); - console.error('错误堆栈:', error.stack); + // 静默失败,尝试下一个方案 + } + + // 方案2: 尝试使用 window.parent.postMessage(安卓备选方案) + if (!messageSent) { + try { + if (window.parent && window.parent !== window) { + window.parent.postMessage(messageData, '*'); + messageSent = true; + } + } catch (error) { + // 静默失败,尝试下一个方案 + } + } + + // 方案3: 尝试使用 window.webkit.messageHandlers(iOS WebView) + if (!messageSent) { + try { + if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.uni) { + window.webkit.messageHandlers.uni.postMessage(messageData); + messageSent = true; + } + } catch (error) { + // 静默失败,尝试下一个方案 + } + } + + // 方案4: 通过 URL 参数方式触发(最可靠的安卓方案,作为最后备选) + if (!messageSent) { + try { + // 获取当前 URL 参数 + const urlParams = new URLSearchParams(window.location.search); + const currentProjectInfo = urlParams.get('projectInfo'); + + // 构建新的 URL,添加模型预览触发参数 + const clickedProjectJson = encodeURIComponent(JSON.stringify(projectInfo)); + const timestamp = Date.now(); + + // 构建完整的新 URL + let newUrl = window.location.pathname; + if (currentProjectInfo) { + newUrl += '?projectInfo=' + encodeURIComponent(currentProjectInfo); + } + newUrl += (currentProjectInfo ? '&' : '?') + 'clickedProject=' + clickedProjectJson; + newUrl += '&action=modelPreview&t=' + timestamp; + + // 使用 location.href 触发页面重新加载 + // 注意:这会触发页面重新加载,但可以通过 URL 参数恢复状态 + window.location.href = newUrl; + return; + } catch (error) { + console.error('发送模型预览消息失败:', error); + alert('无法发送模型预览请求,请重试'); + } } } @@ -483,19 +567,12 @@ // 显示模型预览面板(暴露到全局作用域) window.showModelPreview = function(models, clickedProject) { - console.log('showModelPreview 被调用,模型数量:', models?.length); - console.log('点击的项目信息:', clickedProject); - // 如果传入了点击的项目信息,保存它 if (clickedProject) { currentClickedProject = clickedProject; } - console.log('当前 map 对象:', map); - console.log('当前 allOverlays 数量:', allOverlays.length); - if (!map) { - console.error('地图未初始化,等待地图初始化...'); // 如果地图未初始化,等待一下再试 setTimeout(() => { if (map) { @@ -522,19 +599,18 @@ } // 清空所有覆盖物 - console.log('开始清空覆盖物,当前数量:', allOverlays.length); clearAllOverlays(); - console.log('已清空所有覆盖物'); // 渲染树形结构 treeContainer.innerHTML = ''; if (modelList.length === 0) { - treeContainer.innerHTML = '
暂无模型数据
'; + treeContainer.innerHTML = '
暂无模型数据
'; } else { + console.log('modelList',JSON.stringify(modelList)); modelList.forEach((model, index) => { + const nodeDiv = document.createElement('div'); nodeDiv.className = 'tree-node'; - const itemDiv = document.createElement('div'); itemDiv.className = 'tree-node-item'; @@ -552,23 +628,19 @@ nodeDiv.appendChild(itemDiv); treeContainer.appendChild(nodeDiv); }); - console.log('已渲染', modelList.length, '个模型节点'); } // 显示面板 panel.style.display = 'flex'; - console.log('预览面板已显示'); }; // 带数据的预览函数(用于直接调用) window.showModelPreviewWithData = function(models, clickedProject) { - console.log('showModelPreviewWithData 被调用'); window.showModelPreview(models, clickedProject); }; // 监听 postMessage 消息 window.addEventListener('message', function(event) { - console.log('收到 postMessage:', event.data); if (event.data && event.data.type === 'showModelPreview') { window.showModelPreview(event.data.modelList); } @@ -595,7 +667,6 @@ // 监听来自父组件的消息(用于接收模型列表) // 注意:uni-app 的 web-view 消息传递机制 window.addEventListener('message', function(event) { - console.log('收到 window.message 事件:', event.data); if (event.data && event.data.type === 'showModelPreview') { const models = event.data.modelList; const clickedProject = event.data.clickedProject; @@ -606,7 +677,6 @@ // 也监听 uni 的消息(如果支持) if (typeof uni !== 'undefined' && uni.on) { uni.on('modelPreviewData', function(data) { - console.log('收到 uni 消息:', data); if (data && data.modelList) { window.showModelPreview(data.modelList, data.clickedProject); }