From b9a58b24e011f5f2cfabe1fd999371b99ad6622b Mon Sep 17 00:00:00 2001 From: BianLzhaoMin <11485688+bianliangzhaomin123@user.noreply.gitee.com> Date: Thu, 24 Apr 2025 15:57:25 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=B5=E5=AD=90=E7=9C=8B=E6=9D=BF=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=90=AD=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../css/synthesisQuery/digitalSignage.css | 138 ++++- .../js/synthesisQuery/digitalSignage.js | 503 +++++++++++++++++- .../pages/synthesisQuery/digitalSignage.html | 30 ++ 3 files changed, 662 insertions(+), 9 deletions(-) diff --git a/src/main/resources/static/css/synthesisQuery/digitalSignage.css b/src/main/resources/static/css/synthesisQuery/digitalSignage.css index adc6b1c..2345732 100644 --- a/src/main/resources/static/css/synthesisQuery/digitalSignage.css +++ b/src/main/resources/static/css/synthesisQuery/digitalSignage.css @@ -42,7 +42,8 @@ body { } .scroll-box, -.legend-box { +.legend-box, +.right-drawer-box { position: absolute; background: rgba(0, 0, 0, 0.5); color: #fff; @@ -136,3 +137,138 @@ body { width: 18px; height: 18px; } + +.map-container { + background: rgba(0, 0, 0, 0.5); + color: white; + padding: 10px; + border-radius: 4px; + box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3); + /* min-width: 150px; */ + font-family: Arial, sans-serif; +} + +.map-container h4 { + margin: 0 0 8px 0; + font-size: 16px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + padding-bottom: 5px; +} + +.map-container-item { + padding: 4px 6px; + display: flex; + align-items: center; + justify-content: space-between; + font-size: 14px; +} + +.map-container-item span:first-child { + width: 160px; +} +.map-container-item span:last-child { + min-width: 120px; + text-align: right; +} + +/* 索道信息窗口样式 */ +.map-container-item-ropeway span:first-child { + padding-left: 16px; +} +.map-container-item-ropeway span:last-child { + margin-left: 4px; + min-width: 120px; +} + +/* 交叉信息窗口样式 */ +.map-container-cross { + display: flex; +} +.map-container-cross .map-container-1 { + width: 260px; + padding: 10px; + border-radius: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + box-shadow: none; +} +.map-container-cross .map-container-2 { + width: 220px; + padding: 10px; + border-radius: 0; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: none; +} + +.map-container-cross .map-container-2 h4 { + padding-left: 20px; +} + +/* 右侧抽屉 */ +.right-drawer-box { + top: 50%; + right: 0; + width: 400px; + height: 90%; + transform: translateY(-50%); + display: none; + box-shadow: -2px 0 10px rgba(0, 0, 0, 0.1); + transition: right 0.3s ease-in-out; +} + +/* 打开弹框的三角 */ +.open-drawer-box { + position: absolute; + top: 50%; + right: 0; + transform: translateY(-50%); + width: 0; + height: 0; + border-style: solid; + border-width: 20px 20px 20px 0; + border-color: transparent #d7d7d7 transparent transparent; + z-index: 999; + cursor: pointer; +} + +.close-drawer-btn { + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 0; + height: 0; + border-style: solid; + border-width: 20px 0px 20px 20px; + border-color: transparent transparent transparent #d7d7d7; + z-index: 999; + cursor: pointer; +} + +/* 当抽屉打开时,隐藏三角按钮 */ +.right-drawer-box.open ~ .open-drawer-box { + display: none; +} + +.open { + display: block; +} + +.organization-tree-box { + padding: 20px; + height: calc(100% - 40px); + overflow-y: auto; +} + +.layui-tree-txt { + color: #fff !important; +} + +.layui-tree-icon .layui-icon { + color: #fff !important; +} + +.layui-tree-line .layui-tree-entry:hover .layui-tree-txt { + color: #dfd8d8 !important; +} diff --git a/src/main/resources/static/js/synthesisQuery/digitalSignage.js b/src/main/resources/static/js/synthesisQuery/digitalSignage.js index b7ec05b..8513b69 100644 --- a/src/main/resources/static/js/synthesisQuery/digitalSignage.js +++ b/src/main/resources/static/js/synthesisQuery/digitalSignage.js @@ -1,6 +1,405 @@ -const map = new BMapGL.Map("map-box"); // 创建Map实例 -map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 11); // 初始化地图,设置中心点坐标和地图级别 -map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 +let map = null; + +// 地图配置项 +const config = { + points: [ + { + lng: 116.254, // 向西偏移 + lat: 39.965, // 向北偏移 + title: "点1", + type: 1, + isCompleted: true, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.263, // 保持适当距离 + lat: 39.972, + title: "点2", + type: 1, + isCompleted: true, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.275, // 平滑过渡 + lat: 39.958, + title: "点3", + type: 1, + isCompleted: true, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.285, // 继续向东 + lat: 39.945, + title: "点4", + type: 2, + isCompleted: true, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.298, // 向南偏移 + lat: 39.935, + title: "点5", + type: 2, + isCompleted: false, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.305, // 保持连贯性 + lat: 39.925, + title: "点6", + type: 2, + isCompleted: false, // 是否完成 + isCrossing: false, // 是否跨越 + }, + { + lng: 116.315, // 最终点 + lat: 39.915, + title: "点7", + type: 3, + isCompleted: false, // 是否完成 + isCrossing: true, // 是否跨越 + }, + { + lng: 116.325, // 最远点 + lat: 39.905, + title: "点8", + type: 9, + isCompleted: false, // 是否完成 + isCrossing: true, // 是否跨越 + }, + ], + polyline: { + strokeColor: "#3388ff", // 线条颜色 + strokeWeight: 3, // 线条宽度 + strokeOpacity: 0.8, // 透明度 + strokeStyle: "dashed", // solid(实线)或dashed(虚线) + enableEditing: false, // 是否可编辑 + enableClicking: true, // 是否可点击 + }, +}; + +// 百度地图初始化 +function initMap() { + map = new BMapGL.Map("map-box"); + // 以第一个点为中心初始化地图 + map.centerAndZoom( + new BMapGL.Point(config.points[0].lng, config.points[0].lat), + 11 + ); + map.enableScrollWheelZoom(true); + + map.setMapStyleV2({ + // styleJson: [ + // { + // featureType: "background", + // elementType: "geometry", + // stylers: { + // color: "#f5f5f5", // 浅灰色背景 + // }, + // }, + // { + // featureType: "road", + // elementType: "geometry", + // stylers: { + // visibility: "off", // 隐藏道路 + // }, + // }, + // ], + }); + // map.setMapType(BMAP_EARTH_MAP); // 地球模式 + // map.setDisplayOptions({ + // poiText: false, // 隐藏POI文字 + // poiIcon: false, // 隐藏POI图标 + // building: false, // 隐藏建筑物 + // }); + + // 添加地图控件(可选) + // map.addControl(new BMapGL.NavigationControl()); + // map.addControl(new BMapGL.ScaleControl()); + + // 地图加载完成后添加标点和折线 + map.addEventListener("tilesloaded", function () { + addAllMapPoints(); + addMapLine(); + }); +} + +// 添加标点 +function addAllMapPoints() { + // 清除地图上所有现有的标记 + map.clearOverlays(); + + const bounds = []; + const iconTypeList = { + 1: "/gzDigitalSignage/img/digitalSignage/yellow.png", + 2: "/gzDigitalSignage/img/digitalSignage/green.png", + 3: "/gzDigitalSignage/img/digitalSignage/blue.png", + 4: "/gzDigitalSignage/img/digitalSignage/orange.png", + 5: "/gzDigitalSignage/img/digitalSignage/zt_red.png", + 6: "/gzDigitalSignage/img/digitalSignage/zt_purple.png", + 7: "/gzDigitalSignage/img/digitalSignage/zt_green.png", + 8: "/gzDigitalSignage/img/digitalSignage/white.png", + 9: "/gzDigitalSignage/img/digitalSignage/sd.png", + }; + + // 使用对象记录已添加的点,避免重复 + const addedPoints = {}; + + config.points.forEach((pointData, index) => { + const pointKey = `${pointData.lng},${pointData.lat}`; + + // 如果该坐标点已经添加过标记,则跳过 + if (addedPoints[pointKey]) { + console.warn(`重复的点坐标被跳过: ${pointKey}`); + return; + } + + addedPoints[pointKey] = true; + const point = new BMapGL.Point(pointData.lng, pointData.lat); + bounds.push(point); + + // 检查图标是否存在,不存在则使用默认图标 + const iconUrl = iconTypeList[pointData.type] || iconTypeList[1]; // 默认使用第一个图标 + const myIcon = new BMapGL.Icon(iconUrl, new BMapGL.Size(30, 32), { + anchor: new BMapGL.Size(8, 35), // 修正锚点位置为中心底部 + imageSize: new BMapGL.Size(30, 32), // 与实际图片尺寸一致 + }); + + const marker = new BMapGL.Marker(point, { icon: myIcon }); + + // 添加信息窗口 + + let infoContent = ""; + + if (pointData.type === 9) { + // 索道 + infoContent = ` +
+

+ 索道运输 +

+
+ 索道位置 + 2025-04-24 +
+
+ 索道长度 + 2025-04-24 +
+
+ 最大载重 + 2025-04-24 +
+
+ 安全距离 + 2025-04-24 +
+
+ 最大坡度 + 2025-04-24 +
+
`; + } else if (pointData.isCrossing) { + // 交叉信息 + infoContent = ` +
+
+

+ ${pointData.title} +

+
+ 基础开挖 + 2025-04-24 +
+
+ 基础开挖完成 + 2025-04-24 +
+
+ 基础浇筑完成 + 2025-04-24 +
+
+ 铁塔组立 + 2025-04-24 +
+
+ 铁塔组立完成 + 2025-04-24 +
+
+ 架线施工完成 + 2025-04-24 +
+
+
+

+ 交叉跨越信息 ( ${pointData.title} ) +

+
+ 上层线路 + 550V宁安线 +
+
+ 下层线路 + 220V宁安线 +
+
+ 交叉角度 + 78.5° +
+
+ 垂直距离 + 12.8m +
+
+ 安全裕度 + 4.8m +
+
+
`; + } else { + // 普通信息 + infoContent = ` +
+

+ ${pointData.title} +

+
+ 基础开挖 + 2025-04-24 +
+
+ 基础开挖完成 + 2025-04-24 +
+
+ 基础浇筑完成 + 2025-04-24 +
+
+ 铁塔组立 + 2025-04-24 +
+
+ 铁塔组立完成 + 2025-04-24 +
+
+ 架线施工完成 + 2025-04-24 +
+
`; + } + + // 创建信息窗口,禁用默认样式 + const infoWindow = new BMapGL.InfoWindow(infoContent, { + width: 0, // 宽度设为0,让内容决定宽度 + height: 0, // 高度设为0,让内容决定高度 + offset: new BMapGL.Size(0, -20), // 调整偏移量 + enableAutoPan: true, // 自动平移地图 + enableCloseOnClick: true, // 点击地图不关闭 + }); + + marker.addEventListener("click", function () { + this.openInfoWindow(infoWindow); + + // 移除百度地图默认添加的三角箭头 + setTimeout(() => { + const infoWindowElements = + document.getElementsByClassName("BMap_bubble_pop"); + if (infoWindowElements.length > 0) { + const popup = infoWindowElements[0]; + // 移除箭头元素 + const arrows = + popup.getElementsByClassName("BMap_bubble_arrow"); + while (arrows[0]) { + arrows[0].parentNode.removeChild(arrows[0]); + } + // 移除百度地图添加的额外样式 + popup.style.background = "none"; + popup.style.border = "none"; + popup.style.boxShadow = "none"; + } + }, 50); + }); + + map.addOverlay(marker); + }); + + // 调整视野使所有点可见 + if (bounds.length > 0) { + map.setViewport(bounds); + } +} + +// 添加标点折线(智能绘制虚实线) +function addMapLine() { + if (config.points.length < 2) return; + + // 存储所有线段 + const segments = []; + + // 遍历点数组,创建线段 + for (let i = 0; i < config.points.length - 1; i++) { + const startPoint = config.points[i]; + const endPoint = config.points[i + 1]; + + // 判断两点是否都已完成 + const isSegmentCompleted = + startPoint.isCompleted && endPoint.isCompleted; + + // 创建线段点数组 + const segmentPoints = [ + new BMapGL.Point(startPoint.lng, startPoint.lat), + new BMapGL.Point(endPoint.lng, endPoint.lat), + ]; + + // 设置线段样式 + const segmentOptions = { + strokeColor: getSegmentColor(startPoint, endPoint), // 根据类型获取颜色 + strokeWeight: config.polyline.strokeWeight, + strokeOpacity: config.polyline.strokeOpacity, + enableEditing: config.polyline.enableEditing, + enableClicking: config.polyline.enableClicking, + strokeStyle: isSegmentCompleted ? "solid" : "dashed", + }; + + // 如果是虚线,设置虚线样式 + if (!isSegmentCompleted) { + segmentOptions.strokeDashArray = [10, 5]; + segmentOptions.strokeOpacity = 0.6; // 虚线透明度降低 + } + + // 创建线段并添加到数组 + segments.push(new BMapGL.Polyline(segmentPoints, segmentOptions)); + } + + // 将所有线段添加到地图 + segments.forEach((segment) => map.addOverlay(segment)); +} + +// 根据点类型获取线段颜色 +function getSegmentColor(startPoint, endPoint) { + // 如果两点类型相同,使用该类型对应颜色 + if (startPoint.type === endPoint.type) { + switch (startPoint.type) { + case 1: + return "#3388ff"; // 类型1蓝色 + case 2: + return "#ff9900"; // 类型2橙色 + case 3: + return "#33cc33"; // 类型3绿色 + default: + return config.polyline.strokeColor; + } + } + // 类型不同使用默认颜色 + return config.polyline.strokeColor; +} + +// 初始化地图 +initMap(); // 获取左上角滚动数据源 function getScrollData() { @@ -141,13 +540,101 @@ document.addEventListener("DOMContentLoaded", function () { // 启动动画 requestAnimationFrame(animateScroll); - // 鼠标悬停时暂停滚动 - scrollContent.addEventListener("mouseenter", function () { - scrollSpeed = 0; + // // 鼠标悬停时暂停滚动 + // scrollContent.addEventListener("mouseenter", function () { + // scrollSpeed = 0; + // }); + + // scrollContent.addEventListener("mouseleave", function () { + // scrollSpeed = 30; // 恢复原始速度 + // }); + + const drawer = document.querySelector(".right-drawer-box"); + const openBtn = document.querySelector(".open-drawer-box"); + const closeBtn = document.querySelector(".close-drawer-btn"); + + // 点击三角按钮打开抽屉 + openBtn.addEventListener("click", function () { + drawer.classList.add("open"); + + layui.use(["tree", "jquery"], function () { + var tree = layui.tree; + var $ = layui.jquery; + + // 初始化组织树 + function initOrgTree() { + // 渲染树形结构 + tree.render({ + elem: "#orgTree", // 绑定元素 + id: "orgTree", // 自定义索引 + data: getTreeData(), // 获取数据 + showCheckbox: false, // 是否显示复选框 + isJump: false, // 是否允许点击节点时弹出新窗口 + accordion: true, // 是否开启手风琴模式 + edit: false, // 是否开启节点的操作图标 + onlyIconControl: true, // 是否仅允许节点左侧图标控制展开收缩 + click: function (obj) { + console.log(obj.data); // 点击节点时的回调 + // 这里可以添加点击节点后的处理逻辑 + }, + }); + } + + // 模拟获取树形数据(实际项目中替换为AJAX请求) + function getTreeData() { + return [ + { + title: "总公司", + id: 1, + children: [ + { + title: "技术部", + id: 11, + children: [ + { title: "前端组", id: 111 }, + { title: "后端组", id: 112 }, + { title: "测试组", id: 113 }, + ], + }, + { + title: "市场部", + id: 12, + children: [ + { title: "销售组", id: 121 }, + { title: "推广组", id: 122 }, + ], + }, + { + title: "人事部", + id: 13, + children: [ + { title: "招聘组", id: 131 }, + { title: "培训组", id: 132 }, + ], + }, + ], + }, + ]; + } + + initOrgTree(); + }); }); - scrollContent.addEventListener("mouseleave", function () { - scrollSpeed = 30; // 恢复原始速度 + // 点击关闭按钮关闭抽屉 + closeBtn.addEventListener("click", function () { + drawer.classList.remove("open"); + }); + + // 点击抽屉外部关闭抽屉(可选) + document.addEventListener("click", function (e) { + if ( + drawer.classList.contains("open") && + !drawer.contains(e.target) && + e.target !== openBtn + ) { + drawer.classList.remove("open"); + } }); }); diff --git a/src/main/resources/static/pages/synthesisQuery/digitalSignage.html b/src/main/resources/static/pages/synthesisQuery/digitalSignage.html index 6bdcdf2..afedb71 100644 --- a/src/main/resources/static/pages/synthesisQuery/digitalSignage.html +++ b/src/main/resources/static/pages/synthesisQuery/digitalSignage.html @@ -17,7 +17,22 @@ 电子看板 + @@ -60,6 +75,21 @@ 6 --> + + +
+ +
+
+ + +
+
+
+
+ + +