Merge pull request 'ddj' (#427) from ddj into dev

Reviewed-on: http://git.feashow.cn/clay/tunnel-cloud-web/pulls/427
This commit is contained in:
2025-09-17 02:16:10 +00:00
2 changed files with 1569 additions and 64 deletions

View File

@@ -5,8 +5,34 @@
<!-- @/assets/images/tunnel/img.png--> <!-- @/assets/images/tunnel/img.png-->
<!-- <img :src="'data:image/png;base64,'+siteImage" style="width:3500px;height:1789px" id="imgModel" usemap="#image"--> <!-- <img :src="'data:image/png;base64,'+siteImage" style="width:3500px;height:1789px" id="imgModel" usemap="#image"-->
<!-- alt="" @click="clickHandler">--> <!-- alt="" @click="clickHandler">-->
<div style="display: flex;justify-content: center;align-items: center;position: relative;" >
<div style="display: flex;justify-content: center;align-items: center;position: relative;">
<img src="/images/img.png" alt="" class="imgModel" id="imgModel" usemap="#image" @click="handleImageClick"/> <img src="/images/img.png" alt="" class="imgModel" id="imgModel" usemap="#image" @click="handleImageClick"/>
<!-- 为coordsList中的每个元素创建对应的SVG图层 -->
<svg
v-for="(item, index) in coordsList"
:key="index"
width="1040"
height="646"
viewBox="0 0 600 700"
xmlns="http://www.w3.org/2000/svg"
style="position: absolute; pointer-events: none;"
:style="hoveredAreaIndex==0?'left: -232px;top: 32px; ':hoveredAreaIndex==1?'left: -180px;top: 20px;':'left: -180px;top: 10px;'"
:title="item.title"
v-show="hoveredAreaIndex == index"
>
<polygon
:id="'poly' + index"
:points="convertCoordsToPoints(item.coords)"
fill="rgba(0,150,255,0.3)"
stroke="#0077cc"
stroke-width="2"
style="cursor: pointer; pointer-events: none;"
@click="clickHot(item.tunnelId, item.clickIndex, index)"
/>
</svg>
<!-- 测量模式控制按钮 --> <!-- 测量模式控制按钮 -->
<!-- <div v-if="isMeasuring" style="position: absolute; top: 20px; right: 20px; z-index: 1000;">--> <!-- <div v-if="isMeasuring" style="position: absolute; top: 20px; right: 20px; z-index: 1000;">-->
<!-- <button @click.stop="toggleMeasurementMode" --> <!-- <button @click.stop="toggleMeasurementMode" -->
@@ -27,8 +53,9 @@
</div> </div>
<map name="image" id="image"> <map name="image" id="image">
<area shape="poly" v-for="(item,index) in coordsList" :coords="item.coords" :key="index" alt="" <area shape="poly" v-for="(item,index) in coordsList" :coords="item.coords" :key="index" alt=""
:title="item.title" style="cursor: pointer;" @click="clickHot(item.tunnelId,item.clickIndex)"> :id="'area'+index"
<!-- :href="'/' + item.tunnelId + '/' + siteId"--> :title="item.title" style="cursor: pointer;pointer-events: none;">
<!-- :href="'/' + item.tunnelId + '/' + siteId" @click="clickHot(item.tunnelId,item.clickIndex)"-->
</map> </map>
</div> </div>
<div class="box-top"> <div class="box-top">
@@ -38,7 +65,7 @@
:list="routeList" :list="routeList"
v-if="showMenu" v-if="showMenu"
/> />
<tunnel-title v-if="showTunnelTitle" /> <tunnel-title v-if="showTunnelTitle"/>
<div class="top-length"> <div class="top-length">
<span>隧道总长度: {{ tunnelLength }}</span> <span>隧道总长度: {{ tunnelLength }}</span>
<!-- <span>当前施工长度: {{ constructionLength }}</span>--> <!-- <span>当前施工长度: {{ constructionLength }}</span>-->
@@ -72,7 +99,7 @@
getAlarmList(); getAlarmList();
" "
> >
<Bell /> <Bell/>
</el-icon> </el-icon>
</div> </div>
<div class="current-user"> <div class="current-user">
@@ -212,8 +239,8 @@
clearable clearable
filterable filterable
> >
<el-option label="已读" :value="true" /> <el-option label="已读" :value="true"/>
<el-option label="未读" :value="false" /> <el-option label="未读" :value="false"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
@@ -226,9 +253,9 @@
style="background-color: #011c29;--el-table-border-color: none;" style="background-color: #011c29;--el-table-border-color: none;"
:header-cell-style="{ backgroundColor: '#064B66', color: '#fff', fontSize: '40px', borderBottom: 'none' }" :header-cell-style="{ backgroundColor: '#064B66', color: '#fff', fontSize: '40px', borderBottom: 'none' }"
:data="alarmList"> :data="alarmList">
<el-table-column prop="tunnelName" label="隧道名称" align="center" width="400px" /> <el-table-column prop="tunnelName" label="隧道名称" align="center" width="400px"/>
<el-table-column prop="alarmContent" label="告警信息" align="center" /> <el-table-column prop="alarmContent" label="告警信息" align="center"/>
<el-table-column prop="alarmTime" label="告警时间" align="center" width="480px" /> <el-table-column prop="alarmTime" label="告警时间" align="center" width="480px"/>
<el-table-column prop="lookupStatus" label="查阅状态" align="center" width="200px" <el-table-column prop="lookupStatus" label="查阅状态" align="center" width="200px"
v-if="roleKey !== 'administrator'"> v-if="roleKey !== 'administrator'">
<template #default="scope"> <template #default="scope">
@@ -278,6 +305,8 @@
<div class="left-bottom-icon"></div> <div class="left-bottom-icon"></div>
<div class="right-bottom-icon"></div> <div class="right-bottom-icon"></div>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
@@ -290,9 +319,9 @@ import AirInfo from "@/components/content/airInfo/AirInfo.vue";
import BadGasInfo from "@/components/content/badGasInfo/BadGasInfo.vue"; import BadGasInfo from "@/components/content/badGasInfo/BadGasInfo.vue";
import ManageBtn from "@/components/manageBtn/index.vue"; import ManageBtn from "@/components/manageBtn/index.vue";
import TunnelTitle from "@/components/tunnelTitle/index.vue"; import TunnelTitle from "@/components/tunnelTitle/index.vue";
import { dateFormat } from "@/utils/date.js"; import {dateFormat} from "@/utils/date.js";
import { getToken } from "@/utils/auth"; import {getToken} from "@/utils/auth";
import { useAuthStore } from "@/store/userstore.js"; import {useAuthStore} from "@/store/userstore.js";
import { import {
getLargeScreen, getLargeScreen,
getLargeScreenInfo, getLargeScreenInfo,
@@ -302,11 +331,12 @@ import {
getAlarmDetail, getAlarmDetail,
updateAlarmState, updateAlarmState,
} from "@/api/largeScreen"; } from "@/api/largeScreen";
import { ElMessage, ElMessageBox } from "element-plus"; import {ElMessage, ElMessageBox} from "element-plus";
import { getUserInfo } from "@/api/login"; import {getUserInfo} from "@/api/login";
import { initSceneData } from "@/api/tunnelScene"; import {initSceneData} from "@/api/tunnelScene";
import { getTunnelList } from "@/api/tunnelManage"; import {getTunnelList} from "@/api/tunnelManage";
import { debounce } from "lodash"; import {debounce, unset} from "lodash";
const authStore = useAuthStore(); const authStore = useAuthStore();
const router = useRouter(); const router = useRouter();
const previewId = reactive(router.currentRoute.value.params.tunnelId); const previewId = reactive(router.currentRoute.value.params.tunnelId);
@@ -348,24 +378,42 @@ let isTunnel = reactive(false);
const coordsList = ref([ const coordsList = ref([
{ {
//厂房 //厂房
clickIndex:0, clickIndex: 0,
tunnelId: 98, tunnelId: 98,
title: '厂房', title: '厂房',
coords: '127,418,165,415,175,440,136,556,98,558,106,478', coords: '127,418,165,415,175,440,136,556,98,558,106,478',
}, { }, {
//2#尾水 //2#尾水
clickIndex:2, clickIndex: 2,
tunnelId: 1, tunnelId: 1,
title: '2#尾水隧洞', title: '2#尾水隧洞',
coords: '283,489,840,170,886,67,869,64,831,155,272,471' coords: '283,489,840,170,886,67,869,64,831,155,272,471'
}, { }, {
//5#支洞 //5#支洞
clickIndex:1, clickIndex: 1,
tunnelId: 109, tunnelId: 109,
title: '5#支洞', title: '5#支洞',
coords: '847,74,833,64,819,28,820,79,842,87' coords: '847,74,833,64,819,28,820,79,842,87'
} }
]) ])
// 添加hoveredAreaIndex用于跟踪当前悬停的区域索引
const hoveredAreaIndex = ref(-1);
// 添加用于存储定时器的数组
const hoverTimeouts = ref([]);
// 添加用于转换坐标格式的函数
const convertCoordsToPoints = (coords) => {
// 将 "x1,y1,x2,y2,..." 格式转换为 "x1,y1 x2,y2 ..." 格式
const coordsArray = coords.split(',');
let points = '';
for (let i = 0; i < coordsArray.length; i += 2) {
if (i > 0) points += ' ';
points += coordsArray[i] + ',' + coordsArray[i + 1];
}
return points;
};
const btnList = ref([ const btnList = ref([
{ {
route: "/site", route: "/site",
@@ -399,8 +447,6 @@ const roleKey = ref("");
// 测量模式相关变量 // 测量模式相关变量
const isMeasuring = ref(false); const isMeasuring = ref(false);
const measurementPoints = ref([]); const measurementPoints = ref([]);
let token = getToken(); let token = getToken();
let send = { let send = {
type: "ping", type: "ping",
@@ -433,29 +479,117 @@ onMounted(() => {
}); });
const pts = [{x: 50, y: 50}, {x: 300, y: 80}];
const str = pts.map(p => `${p.x},${p.y}`).join(' ');
// 修改mouseenter和mouseout事件处理使用防抖和更精确的检测
// nextTick(() => {
// const area1 = document.getElementById("area0");
//
// // 添加防抖标志,避免频繁切换
// let hoverTimeout = null;
// let isHovered = false;
//
// if (area1) {
// area1.addEventListener("mouseenter", e => {
// console.log("鼠标进入区域0", e.clientX, e.clientY);
// // 清除之前的定时器
// if (hoverTimeout) {
// clearTimeout(hoverTimeout);
// }
//
// // 设置hover状态
// isHovered = true;
// hoveredAreaIndex.value = 0;
// });
//
// area1.addEventListener("mousemove", e => {
// // 鼠标在区域内移动时保持显示状态
// if (!isHovered) {
// isHovered = true;
// hoveredAreaIndex.value = 0;
// }
// });
//
// area1.addEventListener("mouseleave", e => {
// console.log("鼠标离开区域0", e.clientX, e.clientY);
// // 设置延迟隐藏,避免闪动
// if (hoverTimeout) {
// clearTimeout(hoverTimeout);
// }
//
// hoverTimeout = setTimeout(() => {
// isHovered = false;
// hoveredAreaIndex.value = 0;
// }, 100); // 100ms延迟
// });
// }
// });
nextTick(() => {
// 为所有area元素添加事件监听
setTimeout(() => {
const areas = document.querySelectorAll('map[name="image"] area');
let hoverTimeout = null;
areas.forEach((area, index) => {
console.log('area, index', area, index)
// 添加防抖定时器
area.addEventListener("mouseenter", () => {
// 清除之前的定时器
if (hoverTimeout) {
clearTimeout(hoverTimeout);
}
// 设置当前悬停的区域索引
hoveredAreaIndex.value = index;
});
area.addEventListener("mouseleave", () => {
// 设置延迟隐藏,避免闪动
if (hoverTimeout) {
clearTimeout(hoverTimeout);
}
hoverTimeout = setTimeout(() => {
// 只有当当前悬停的还是这个区域时才隐藏
if (hoveredAreaIndex.value === index) {
hoveredAreaIndex.value = -1;
}
}, 150); // 150ms延迟
});
});
}, 100);
})
function convertCoordsToArray(coordsArray) { function convertCoordsToArray(coordsArray) {
return coordsArray.map(point => `${point.x},${point.y}`).join(','); return coordsArray.map(point => `${point.x},${point.y}`).join(',');
} }
// 示例使用: // 示例使用:
const coordsData = [ const coordsData = [
{ x: 163, y: 487 }, {x: 163, y: 487},
{ x: 153, y: 483 }, {x: 153, y: 483},
{ x: 217, y: 480 }, {x: 217, y: 480},
{ x: 170, y: 644 }, {x: 170, y: 644},
{ x: 111, y: 640 }, {x: 111, y: 640},
{ x: 145, y: 483 } {x: 145, y: 483}
]; ];
const result = convertCoordsToArray(coordsData); const result = convertCoordsToArray(coordsData);
console.log(result); console.log(result);
// 输出: "163,487,153,483,217,480,170,644,111,640,145,483" // 输出: "163,487,153,483,217,480,170,644,111,640,145,483"
const clickHot = (id,index) => { const clickHot = (id, index, areaIndex) => {
console.log('点击热区===============') console.log('点击热区===============')
initialIndex.value=index initialIndex.value = index
changeTunnel(index) changeTunnel(index)
tunnelBtn.value.setActiveItem(index); tunnelBtn.value.setActiveItem(index);
}
// 点击时也设置hoveredAreaIndex确保点击的区域高亮显示
if (areaIndex !== undefined) {
hoveredAreaIndex.value = areaIndex;
}
};
const changeName = (id) => { const changeName = (id) => {
for (let item of equipmentOption.value) { for (let item of equipmentOption.value) {
if (item.value === id) { if (item.value === id) {
@@ -683,7 +817,7 @@ const getTunnel = (id) => {
const changeTunnel = (e) => { const changeTunnel = (e) => {
// console.info("🚀 ~method:'tunnelList.value' -----", tunnelList.value) // console.info("🚀 ~method:'tunnelList.value' -----", tunnelList.value)
console.info("🚀 ~method:'changeTunnel' -----", e) console.info("🚀 ~method:'changeTunnel' -----", e)
if(socket){ if (socket) {
socket.close() socket.close()
} }
let newObj = {} let newObj = {}
@@ -727,12 +861,12 @@ const manageSelect = (name) => {
router.push("/simulate/tunnel/list"); router.push("/simulate/tunnel/list");
} }
} }
if(socket){ if (socket) {
socket.close() socket.close()
} }
}; };
const handleChangeSite = debounce((item) => { const handleChangeSite = debounce((item) => {
if(socket){ if (socket) {
socket.close() socket.close()
} }
currentSite.value = item.label currentSite.value = item.label
@@ -847,7 +981,7 @@ const toggleMeasurementMode = () => {
const handleImageClick = (event) => { const handleImageClick = (event) => {
// 如果不是测量模式执行原来的getInfo逻辑 // 如果不是测量模式执行原来的getInfo逻辑
if (!isMeasuring.value) { if (!isMeasuring.value) {
getInfo(); // getInfo();
return; return;
} }
@@ -860,7 +994,7 @@ const handleImageClick = (event) => {
const y = event.clientY - rect.top; const y = event.clientY - rect.top;
// 添加坐标到数组 // 添加坐标到数组
measurementPoints.value.push({ x: Math.round(x), y: Math.round(y) }); measurementPoints.value.push({x: Math.round(x), y: Math.round(y)});
// 在点击位置创建一个视觉反馈点 // 在点击位置创建一个视觉反馈点
const pointElement = document.createElement('div'); const pointElement = document.createElement('div');
@@ -890,31 +1024,31 @@ const clearMeasurementPoints = () => {
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.alarm-tunnel .device-table{ .alarm-tunnel .device-table {
height: 1158px !important;
height: 1158px!important;
overflow-y: scroll; overflow-y: scroll;
.el-dialog__body{
height: 1158px!important; .el-dialog__body {
height: 1158px !important;
overflow-y: scroll; overflow-y: scroll;
} }
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 16px; width: 16px;
} }
// 滚动条轨道
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background: transparent; background: transparent;
border-radius: 2px; border-radius: 2px;
} }
// 小滑块
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background: rgb(8, 183, 184); background: rgb(8, 183, 184);
border-radius: 10px; border-radius: 10px;
} }
} }
.el-drawer__header { .el-drawer__header {
display: none; display: none;
} }
@@ -926,7 +1060,6 @@ const clearMeasurementPoints = () => {
.el-dropdown__popper.el-popper { .el-dropdown__popper.el-popper {
background: transparent; background: transparent;
//border: none;
border: 1px solid #0e7daa; border: 1px solid #0e7daa;
border-radius: 10px; border-radius: 10px;
} }
@@ -946,9 +1079,7 @@ const clearMeasurementPoints = () => {
.el-dropdown-menu__item { .el-dropdown-menu__item {
color: #ffffff; color: #ffffff;
//border:none;
padding: 5px; padding: 5px;
border-bottom: 1px solid #05feff; border-bottom: 1px solid #05feff;
&:last-child { &:last-child {
@@ -969,18 +1100,21 @@ const clearMeasurementPoints = () => {
background: rgba(7, 35, 72, 0.9); background: rgba(7, 35, 72, 0.9);
} }
} }
</style>
<style lang="scss" scoped> .points {
background-color: red;
z-index: 2222222222222222222;
}
#main { #main {
height: 100%; height: 100%;
width: 100%; width: 100%;
//background-color: #072348;
background-image: url('/images/background/background.png'); background-image: url('/images/background/background.png');
#tunnel-box { #tunnel-box {
height: 100%; height: 100%;
} }
.img-box { .img-box {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -991,7 +1125,8 @@ const clearMeasurementPoints = () => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.imgModel{
.imgModel {
width: 1040px; width: 1040px;
height: 646px; height: 646px;
} }
@@ -1010,7 +1145,6 @@ const clearMeasurementPoints = () => {
:deep(.el-table--fit) { :deep(.el-table--fit) {
width: auto; width: auto;
//height: 600px;
background-color: transparent !important; background-color: transparent !important;
.el-loading-mask { .el-loading-mask {
@@ -1028,7 +1162,6 @@ const clearMeasurementPoints = () => {
:deep(.el-table__empty-block) { :deep(.el-table__empty-block) {
height: 200px !important; height: 200px !important;
//display: none;
.el-table__empty-text { .el-table__empty-text {
font-size: 60px; font-size: 60px;
color: #08b7b8; color: #08b7b8;
@@ -1174,7 +1307,6 @@ const clearMeasurementPoints = () => {
} }
:deep(.el-table--fit) { :deep(.el-table--fit) {
//width: 1780px !important;
width: auto; width: auto;
} }
@@ -1189,9 +1321,7 @@ const clearMeasurementPoints = () => {
background-color: #1c5971; background-color: #1c5971;
} }
:deep( :deep(.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell) {
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell
) {
background-color: #1c5971; background-color: #1c5971;
} }
@@ -1199,12 +1329,7 @@ const clearMeasurementPoints = () => {
background-color: #13849c !important; background-color: #13849c !important;
} }
:deep( :deep(.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell) {
.el-table--striped
.el-table__body
tr.el-table__row--striped
td.el-table__cell
) {
background-color: #13849c !important; background-color: #13849c !important;
} }

File diff suppressed because it is too large Load Diff