2025-07-29 09:25:24 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
2025-07-31 01:33:54 +08:00
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
|
|
|
|
|
|
<script type="text/javascript"
|
2025-10-28 10:18:47 +08:00
|
|
|
|
src="https://api.map.baidu.com/api?v=3.0&&type=webgl&ak=iqyZkSZPurf61MhFV7hesbDukHdMBEEb"></script>
|
2025-07-31 01:33:54 +08:00
|
|
|
|
|
2025-07-29 09:25:24 +08:00
|
|
|
|
<title>百度地图</title>
|
|
|
|
|
|
<style>
|
|
|
|
|
|
#map-container {
|
|
|
|
|
|
width: 100vw;
|
|
|
|
|
|
height: 100vh;
|
2026-01-12 13:35:59 +08:00
|
|
|
|
position: relative;
|
2025-07-29 09:25:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 去除百度地图的水印和logo */
|
|
|
|
|
|
.BMap_cpyCtrl,
|
|
|
|
|
|
.anchorBL {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
2026-01-12 13:35:59 +08:00
|
|
|
|
|
|
|
|
|
|
/* 模型预览面板 */
|
|
|
|
|
|
.model-preview-panel {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
background: rgba(0, 0, 0, 0.3);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-preview-tree {
|
|
|
|
|
|
width: 300px;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-right: 1px solid #e0e0e0;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-title {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
padding-bottom: 10px;
|
|
|
|
|
|
border-bottom: 2px solid #002db6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-node {
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-node-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
transition: background-color 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-node-item:hover {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-node-checkbox {
|
|
|
|
|
|
width: 18px;
|
|
|
|
|
|
height: 18px;
|
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tree-node-label {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
user-select: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-preview-close {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 20px;
|
|
|
|
|
|
right: 20px;
|
|
|
|
|
|
width: 40px;
|
|
|
|
|
|
height: 40px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
z-index: 1001;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-preview-close:hover {
|
|
|
|
|
|
background: #f5f5f5;
|
|
|
|
|
|
transform: scale(1.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-preview-close::before,
|
|
|
|
|
|
.model-preview-close::after {
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 2px;
|
|
|
|
|
|
height: 20px;
|
|
|
|
|
|
background: #666;
|
|
|
|
|
|
transform: rotate(45deg);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.model-preview-close::after {
|
|
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 点击菜单样式 */
|
|
|
|
|
|
.action-menu {
|
|
|
|
|
|
background: linear-gradient(180deg, #ffffff 0%, #fafbfc 100%);
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
box-shadow: 0 8px 32px rgba(0, 45, 182, 0.12),
|
|
|
|
|
|
0 4px 16px rgba(0, 0, 0, 0.08),
|
|
|
|
|
|
0 2px 8px rgba(0, 0, 0, 0.04);
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
border: 1px solid rgba(0, 45, 182, 0.08);
|
|
|
|
|
|
backdrop-filter: blur(10px);
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
justify-content: stretch;
|
|
|
|
|
|
align-items: stretch;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item {
|
|
|
|
|
|
padding: 0 20px;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: flex-start;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
letter-spacing: 0.2px;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
border-bottom: 1px solid rgba(0, 45, 182, 0.06);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item:first-child {
|
|
|
|
|
|
border-radius: 16px 16px 0 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item:last-child {
|
|
|
|
|
|
border-bottom: none;
|
|
|
|
|
|
border-radius: 0 0 16px 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item::before {
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 50%;
|
|
|
|
|
|
transform: translateY(-50%);
|
|
|
|
|
|
width: 3px;
|
|
|
|
|
|
height: 0;
|
|
|
|
|
|
background: linear-gradient(180deg, #002db6 0%, #0056e6 100%);
|
|
|
|
|
|
border-radius: 0 2px 2px 0;
|
|
|
|
|
|
opacity: 0;
|
|
|
|
|
|
transition: all 0.25s ease;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item:hover {
|
|
|
|
|
|
background: linear-gradient(135deg, #f0f4ff 0%, #e6edff 100%);
|
|
|
|
|
|
color: #002db6;
|
|
|
|
|
|
padding-left: 24px;
|
|
|
|
|
|
transform: translateX(2px);
|
|
|
|
|
|
box-shadow: inset 0 0 0 1px rgba(0, 45, 182, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item:hover::before {
|
|
|
|
|
|
opacity: 1;
|
|
|
|
|
|
height: 60%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item span {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
|
width: 24px;
|
|
|
|
|
|
height: 24px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.action-menu-item:hover span {
|
|
|
|
|
|
transform: scale(1.15) rotate(5deg);
|
|
|
|
|
|
}
|
2025-07-29 09:25:24 +08:00
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div id="map-container"></div>
|
2026-01-12 13:35:59 +08:00
|
|
|
|
<!-- 模型预览面板 -->
|
|
|
|
|
|
<div id="model-preview-panel" class="model-preview-panel" style="display: none;">
|
|
|
|
|
|
<div class="model-preview-tree">
|
|
|
|
|
|
<div class="tree-title">模型列表</div>
|
|
|
|
|
|
<div id="tree-container"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="model-preview-close" id="close-preview-btn"></div>
|
|
|
|
|
|
</div>
|
2025-07-31 01:33:54 +08:00
|
|
|
|
</body>
|
2025-07-29 09:25:24 +08:00
|
|
|
|
|
2025-07-31 01:33:54 +08:00
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
document.addEventListener('UniAppJSBridgeReady', function () {
|
2026-01-12 13:35:59 +08:00
|
|
|
|
// 全局变量
|
|
|
|
|
|
let map = null;
|
|
|
|
|
|
let allOverlays = []; // 保存所有覆盖物
|
|
|
|
|
|
let currentClickedProject = null; // 当前点击的项目信息
|
|
|
|
|
|
let modelList = []; // 模型列表
|
2025-08-01 17:02:21 +08:00
|
|
|
|
|
|
|
|
|
|
function getUrlParams() {
|
|
|
|
|
|
const params = new URLSearchParams(window.location.search);
|
2025-09-23 16:16:46 +08:00
|
|
|
|
const projectInfo = JSON.parse(params.get('projectInfo'))
|
|
|
|
|
|
return projectInfo
|
2025-08-01 17:02:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-23 16:16:46 +08:00
|
|
|
|
const projectInfo = getUrlParams()
|
2025-08-01 17:02:21 +08:00
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
// 检查 URL 参数中是否有模型预览请求
|
|
|
|
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
|
|
|
|
const modelListParam = urlParams.get('modelList');
|
|
|
|
|
|
const actionParam = urlParams.get('action');
|
|
|
|
|
|
const clickedProjectParam = urlParams.get('clickedProject');
|
|
|
|
|
|
|
|
|
|
|
|
// 保存点击的项目信息
|
|
|
|
|
|
if (clickedProjectParam) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
currentClickedProject = JSON.parse(decodeURIComponent(clickedProjectParam));
|
|
|
|
|
|
console.log('保存点击的项目信息:', currentClickedProject);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error('解析点击项目信息失败:', e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先初始化地图
|
2025-09-23 16:16:46 +08:00
|
|
|
|
initMap(projectInfo)
|
2026-01-12 13:35:59 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 等待地图初始化完成后再显示预览
|
|
|
|
|
|
setTimeout(showPreviewWhenReady, 500);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error('解析模型列表失败:', e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-01 17:02:21 +08:00
|
|
|
|
|
|
|
|
|
|
function initMap(proInfo) {
|
2026-01-12 13:35:59 +08:00
|
|
|
|
map = new BMapGL.Map('map-container') // 创建地图实例
|
2025-09-23 16:16:46 +08:00
|
|
|
|
let point = new BMapGL.Point(proInfo[0].lng, proInfo[0].lat) // 创建点坐标
|
2025-08-01 17:02:21 +08:00
|
|
|
|
map.centerAndZoom(point, 12) // 初始化地图,设置中心点坐标和地图级别
|
|
|
|
|
|
map.enableScrollWheelZoom(true) // 启用滚轮放大缩小
|
2025-09-23 16:16:46 +08:00
|
|
|
|
projectInfo.forEach(item => {
|
|
|
|
|
|
handleProjectInfoOnMap(map, item)
|
|
|
|
|
|
})
|
2025-08-01 17:02:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function handleProjectInfoOnMap(map, projectInfo) {
|
|
|
|
|
|
if (projectInfo.lng && projectInfo.lat) {
|
|
|
|
|
|
const projectPoint = new BMapGL.Point(projectInfo.lng, projectInfo.lat);
|
|
|
|
|
|
const icon = new BMapGL.Icon('./image/location.png', new BMapGL.Size(36, 36), {
|
2026-01-12 13:35:59 +08:00
|
|
|
|
anchor: new BMapGL.Size(12, 24),
|
2025-08-01 17:02:21 +08:00
|
|
|
|
})
|
2026-01-12 13:35:59 +08:00
|
|
|
|
|
2025-08-01 17:02:21 +08:00
|
|
|
|
const marker = new BMapGL.Marker(projectPoint, {
|
|
|
|
|
|
icon: icon,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-01-12 10:13:52 +08:00
|
|
|
|
const label = new BMapGL.Label(`${projectInfo.proName} (${projectInfo.declination})`, {
|
2025-08-01 17:02:21 +08:00
|
|
|
|
position: projectPoint,
|
2026-01-12 13:35:59 +08:00
|
|
|
|
offset: new BMapGL.Size(0, 0),
|
2025-08-01 17:02:21 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
label.setStyle({
|
|
|
|
|
|
color: '#002db6',
|
|
|
|
|
|
backgroundColor: 'transparent',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
padding: '5px',
|
|
|
|
|
|
whiteSpace: 'nowrap',
|
|
|
|
|
|
fontSize: '18px',
|
|
|
|
|
|
fontWeight: 'bold',
|
2026-01-12 13:35:59 +08:00
|
|
|
|
transform: 'translateX(-45%)'
|
2025-08-01 17:02:21 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
map.addOverlay(marker)
|
2025-08-01 17:02:21 +08:00
|
|
|
|
map.addOverlay(label)
|
2026-01-12 13:35:59 +08:00
|
|
|
|
|
|
|
|
|
|
// 保存覆盖物引用
|
|
|
|
|
|
allOverlays.push({
|
|
|
|
|
|
marker: marker,
|
|
|
|
|
|
label: label,
|
|
|
|
|
|
projectInfo: projectInfo,
|
|
|
|
|
|
point: projectPoint
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-08-01 17:02:21 +08:00
|
|
|
|
marker.addEventListener('click', function () {
|
2026-01-12 13:35:59 +08:00
|
|
|
|
currentClickedProject = projectInfo;
|
|
|
|
|
|
showActionMenu(projectPoint, projectInfo);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示操作菜单
|
|
|
|
|
|
function showActionMenu(point, projectInfo) {
|
|
|
|
|
|
const menuHtml = `
|
|
|
|
|
|
<div class="action-menu" style="overflow: hidden !important; padding: 0 !important; margin: 0 !important; box-sizing: border-box !important; width: 100% !important; height: 100% !important;">
|
|
|
|
|
|
<div class="action-menu-item" data-action="preview">
|
|
|
|
|
|
<span>🗺️</span>模型预览
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="action-menu-item" data-action="survey">
|
|
|
|
|
|
<span>📋</span>勘察
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`;
|
2025-09-23 16:16:46 +08:00
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
const infoWindow = new BMapGL.InfoWindow(menuHtml, {
|
|
|
|
|
|
width: 170,
|
|
|
|
|
|
height: 130,
|
|
|
|
|
|
title: '',
|
|
|
|
|
|
enableMessage: false,
|
|
|
|
|
|
offset: new BMapGL.Size(0, -20),
|
|
|
|
|
|
enableAutoPan: true
|
|
|
|
|
|
});
|
2025-09-23 16:16:46 +08:00
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
map.openInfoWindow(infoWindow, point);
|
|
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
const menuContainer = document.querySelector('.action-menu');
|
|
|
|
|
|
if (menuContainer) {
|
|
|
|
|
|
menuContainer.addEventListener('click', function(e) {
|
|
|
|
|
|
const target = e.target.closest('.action-menu-item');
|
|
|
|
|
|
if (!target) return;
|
|
|
|
|
|
|
|
|
|
|
|
const action = target.getAttribute('data-action');
|
|
|
|
|
|
map.closeInfoWindow();
|
|
|
|
|
|
|
|
|
|
|
|
if (action === 'survey') {
|
|
|
|
|
|
// 勘察 - 原来的逻辑
|
|
|
|
|
|
console.log('发送勘察消息:', projectInfo);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
uni.postMessage({
|
|
|
|
|
|
data: {
|
|
|
|
|
|
action: 'navigateToProject',
|
|
|
|
|
|
projectInfo: projectInfo
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
console.log('勘察消息已发送');
|
|
|
|
|
|
} 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);
|
|
|
|
|
|
}
|
2025-09-23 16:16:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2026-01-12 13:35:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
}, 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: {
|
|
|
|
|
|
action: 'modelPreview',
|
|
|
|
|
|
projectInfo: projectInfo
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('准备发送的消息数据:', messageData);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (typeof uni === 'undefined') {
|
|
|
|
|
|
console.error('uni 对象未定义!');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清空所有覆盖物
|
|
|
|
|
|
function clearAllOverlays() {
|
|
|
|
|
|
allOverlays.forEach(overlay => {
|
|
|
|
|
|
map.removeOverlay(overlay.marker);
|
|
|
|
|
|
map.removeOverlay(overlay.label);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 恢复所有覆盖物
|
|
|
|
|
|
function restoreAllOverlays() {
|
|
|
|
|
|
allOverlays.forEach(overlay => {
|
|
|
|
|
|
map.addOverlay(overlay.marker);
|
|
|
|
|
|
map.addOverlay(overlay.label);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 定位到指定坐标
|
|
|
|
|
|
function locateToPoint(point, zoom = 15) {
|
|
|
|
|
|
map.centerAndZoom(point, zoom);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示模型预览面板(暴露到全局作用域)
|
|
|
|
|
|
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) {
|
|
|
|
|
|
window.showModelPreview(models, clickedProject);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('地图初始化超时');
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
modelList = models || [];
|
|
|
|
|
|
const panel = document.getElementById('model-preview-panel');
|
|
|
|
|
|
const treeContainer = document.getElementById('tree-container');
|
|
|
|
|
|
|
|
|
|
|
|
if (!panel) {
|
|
|
|
|
|
console.error('找不到预览面板元素 #model-preview-panel');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!treeContainer) {
|
|
|
|
|
|
console.error('找不到树容器元素 #tree-container');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清空所有覆盖物
|
|
|
|
|
|
console.log('开始清空覆盖物,当前数量:', allOverlays.length);
|
|
|
|
|
|
clearAllOverlays();
|
|
|
|
|
|
console.log('已清空所有覆盖物');
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染树形结构
|
|
|
|
|
|
treeContainer.innerHTML = '';
|
|
|
|
|
|
if (modelList.length === 0) {
|
|
|
|
|
|
treeContainer.innerHTML = '<div style="color: #999; text-align: center; padding: 20px;">暂无模型数据</div>';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
modelList.forEach((model, index) => {
|
|
|
|
|
|
const nodeDiv = document.createElement('div');
|
|
|
|
|
|
nodeDiv.className = 'tree-node';
|
|
|
|
|
|
|
|
|
|
|
|
const itemDiv = document.createElement('div');
|
|
|
|
|
|
itemDiv.className = 'tree-node-item';
|
|
|
|
|
|
|
|
|
|
|
|
const checkbox = document.createElement('input');
|
|
|
|
|
|
checkbox.type = 'checkbox';
|
|
|
|
|
|
checkbox.className = 'tree-node-checkbox';
|
|
|
|
|
|
checkbox.checked = false;
|
|
|
|
|
|
|
|
|
|
|
|
const label = document.createElement('span');
|
|
|
|
|
|
label.className = 'tree-node-label';
|
|
|
|
|
|
label.textContent = model.name || model.modelName || model.label || `模型 ${index + 1}`;
|
|
|
|
|
|
|
|
|
|
|
|
itemDiv.appendChild(checkbox);
|
|
|
|
|
|
itemDiv.appendChild(label);
|
|
|
|
|
|
nodeDiv.appendChild(itemDiv);
|
|
|
|
|
|
treeContainer.appendChild(nodeDiv);
|
2025-08-01 17:02:21 +08:00
|
|
|
|
});
|
2026-01-12 13:35:59 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭模型预览面板
|
|
|
|
|
|
function closeModelPreview() {
|
|
|
|
|
|
const panel = document.getElementById('model-preview-panel');
|
|
|
|
|
|
panel.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
|
|
// 恢复所有覆盖物
|
|
|
|
|
|
restoreAllOverlays();
|
|
|
|
|
|
|
|
|
|
|
|
// 定位到点击的坐标
|
|
|
|
|
|
if (currentClickedProject && currentClickedProject.lng && currentClickedProject.lat) {
|
|
|
|
|
|
const point = new BMapGL.Point(currentClickedProject.lng, currentClickedProject.lat);
|
|
|
|
|
|
locateToPoint(point, 15);
|
2025-08-01 17:02:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
// 绑定关闭按钮事件
|
|
|
|
|
|
document.getElementById('close-preview-btn').addEventListener('click', closeModelPreview);
|
2025-07-31 01:33:54 +08:00
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
// 监听来自父组件的消息(用于接收模型列表)
|
|
|
|
|
|
// 注意: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;
|
|
|
|
|
|
window.showModelPreview(models, clickedProject);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2025-08-01 17:02:21 +08:00
|
|
|
|
|
2026-01-12 13:35:59 +08:00
|
|
|
|
// 也监听 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-07-31 01:33:54 +08:00
|
|
|
|
</script>
|
2025-07-29 09:25:24 +08:00
|
|
|
|
|
|
|
|
|
|
</html>
|