服务区弹框

This commit is contained in:
fengshiwang 2025-06-06 16:53:45 +08:00
parent 9ec6f41e6f
commit 01d8de7f11
6 changed files with 238 additions and 124 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -17,7 +17,7 @@
</div>
<div class="info-item">
<span class="info-label">设备编号</span>
<span class="info-value blue-value">{{ props.deviceInfo.deviceCode }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.deviceId }}</span>
</div>
</div>
<div class="info-row">
@ -31,21 +31,21 @@
</div>
<div class="info-item">
<span class="info-label">桩号</span>
<span class="info-value blue-value">{{ props.deviceInfo.stakeNumber }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.pilEnum }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">经度</span>
<span class="info-value blue-value">{{ props.deviceInfo.longitude }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.lon }}</span>
</div>
<div class="info-item">
<span class="info-label">维度</span>
<span class="info-value blue-value">{{ props.deviceInfo.latitude }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.lat }}</span>
</div>
<div class="info-item">
<span class="info-label">IP</span>
<span class="info-value blue-value">{{ props.deviceInfo.ipAddress }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.ip }}</span>
</div>
</div>
</div>
@ -67,7 +67,7 @@
</template>
<script setup>
import { ref, nextTick, onMounted } from "vue";
// props
const props = defineProps({
deviceInfo: {
@ -76,6 +76,9 @@ const props = defineProps({
})
}
});
onMounted(()=>{
console.log(props.deviceInfo, 'ddddddddddddd')
})
</script>
<style scoped lang="scss">

View File

@ -12,12 +12,12 @@
<span class="info-value blue-value">{{ props.deviceInfo.deviceType }}</span>
</div>
<div class="info-item">
<span class="info-label">可变信息标志</span>
<span class="info-label">摄像机类型</span>
<span class="info-value blue-value">{{ props.deviceInfo.cameraType }}</span>
</div>
<div class="info-item">
<span class="info-label">设备编号</span>
<span class="info-value blue-value">{{ props.deviceInfo.deviceCode }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.deviceId }}</span>
</div>
</div>
<div class="info-row">
@ -31,21 +31,21 @@
</div>
<div class="info-item">
<span class="info-label">桩号</span>
<span class="info-value blue-value">{{ props.deviceInfo.stakeNumber }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.pilEnum }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">经度</span>
<span class="info-value blue-value">{{ props.deviceInfo.longitude }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.lon }}</span>
</div>
<div class="info-item">
<span class="info-label">维度</span>
<span class="info-value blue-value">{{ props.deviceInfo.latitude }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.lat }}</span>
</div>
<div class="info-item">
<span class="info-label">IP</span>
<span class="info-value blue-value">{{ props.deviceInfo.ipAddress }}</span>
<span class="info-value blue-value">{{ props.deviceInfo.ip }}</span>
</div>
</div>
</div>

View File

@ -1,8 +1,9 @@
<script setup lang="ts">
import { ref } from "vue";
import { ref, onMounted } from "vue";
import demoImage from "@/assets/img/demo.png";
import fwqImage from "@/assets/img/fwq.png";
import { getVideoDeviceList, videoStream } from "@/api/modules/index";
import dayjs from "dayjs";
//
const deviceStatus = ref({
normal: 248,
@ -25,50 +26,42 @@ const parkingData = ref([
//
const monitoringGroups = ref([
{
id: 1,
name: "邯港方向",
count: 5,
expanded: true,
points: [
{ id: 1, name: "邯港方向监控001", status: "正常" },
{ id: 2, name: "邯港方向监控002", status: "正常" },
{ id: 3, name: "邯港方向监控003", status: "正常" },
{ id: 4, name: "邯港方向监控004", status: "正常" },
{ id: 5, name: "邯港方向监控005", status: "正常" },
],
},
{
id: 2,
name: "黄驿港方向",
count: 12,
expanded: false,
points: [],
},
{
id: 3,
name: "收费站",
count: 5,
expanded: true,
points: [
{ id: 6, name: "收费站监控001", status: "正常" },
{ id: 7, name: "收费站监控002", status: "正常" },
{ id: 8, name: "收费站监控003", status: "正常" },
{ id: 9, name: "收费站监控004", status: "正常" },
],
},
// {
// id: 1,
// name: "",
// count: 5,
// expanded: true,
// points: [
// { id: 1, name: "001", status: "" },
// { id: 2, name: "002", status: "" },
// { id: 3, name: "003", status: "" },
// { id: 4, name: "004", status: "" },
// { id: 5, name: "005", status: "" },
// ],
// },
// {
// id: 2,
// name: "驿",
// count: 12,
// expanded: false,
// points: [],
// },
// {
// id: 3,
// name: "",
// count: 5,
// expanded: true,
// points: [
// { id: 6, name: "001", status: "" },
// { id: 7, name: "002", status: "" },
// { id: 8, name: "003", status: "" },
// { id: 9, name: "004", status: "" },
// ],
// },
]);
//
const fixedRoadMonitors = ref([
{ id: 101, name: "高速公路监控001", image: demoImage },
{ id: 102, name: "高速公路监控002", image: demoImage },
{ id: 103, name: "高速公路监控003", image: demoImage },
{ id: 104, name: "高速公路监控004", image: demoImage },
{ id: 105, name: "高速公路监控005", image: demoImage },
{ id: 106, name: "高速公路监控006", image: demoImage },
{ id: 107, name: "高速公路监控007", image: demoImage },
{ id: 108, name: "高速公路监控008", image: demoImage },
]);
//
@ -80,14 +73,58 @@ const toggleGroup = (group: any) => {
const selectedPoints = ref<any[]>([]);
//
const togglePoint = (point: any) => {
const index = selectedPoints.value.findIndex((p) => p.id === point.id);
// const togglePoint = (point: any) => {
// const index = selectedPoints.value.findIndex((p) => p.id === point.id);
// if (index > -1) {
// selectedPoints.value.splice(index, 1);
// } else {
// selectedPoints.value.push(point);
// }
// };
const togglePoint = async (point: any) => {
const index = selectedPoints.value.findIndex((p) => p.channelCode === point.channelCode);
if (index > -1) {
//
selectedPoints.value.splice(index, 1);
const monitorIdx = fixedRoadMonitors.value.findIndex(m => m.channelCode === point.channelCode);
if (monitorIdx > -1) {
fixedRoadMonitors.value.splice(monitorIdx, 1);
}
} else {
// 8
if (selectedPoints.value.length >= 8) {
const removed = selectedPoints.value.shift();
// fixedRoadMonitors
const rmIdx = fixedRoadMonitors.value.findIndex(m => m.channelCode === removed.channelCode);
if (rmIdx > -1) fixedRoadMonitors.value.splice(rmIdx, 1);
}
selectedPoints.value.push(point);
// fixedRoadMonitors
const res = await videoStream({ deviceCode: point.deviceCode, channelCode: point.channelCode });
// fixedRoadMonitors6
if (fixedRoadMonitors.value.length >= 8) {
fixedRoadMonitors.value.shift();
}
fixedRoadMonitors.value.push({
...point,
src: res
});
}
};
onMounted(() => {
const endTime = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss');
getVideoDeviceList({ endTime: endTime, currentPage: 1, pageSize: 2 }).then((res) => { //
console.log(res, 'rrrrrrrrrrrrrrrrrrrrrrrrrsssssssssssss')
if (res.code == 200) {
res.data.data.forEach((item) => {
item.expanded = true
})
monitoringGroups.value = res.data.data
}
console.log(monitoringGroups.value, 'monitoringGroups.value')
})
})
</script>
<template>
@ -123,11 +160,7 @@ const togglePoint = (point: any) => {
<!-- 添加车位信息展示 -->
<div class="parking-info">
<div
v-for="(item, index) in parkingData"
:key="index"
class="parking-item"
>
<div v-for="(item, index) in parkingData" :key="index" class="parking-item">
<div class="parking-label">{{ item.label }}</div>
<div class="parking-value">{{ item.value }}</div>
</div>
@ -142,38 +175,22 @@ const togglePoint = (point: any) => {
<span>视频监控列表</span>
</div>
<div class="list-content">
<div
v-for="group in monitoringGroups"
:key="group.id"
class="group-item"
>
<div v-for="(group, index) in monitoringGroups" :key="index" class="group-item">
<div class="group-header" @click="toggleGroup(group)">
<div class="group-name">
<i class="arrow" :class="{ expanded: group.expanded }"></i>
<span style="font-size: 22.5px"
>{{ group.name }}{{ group.count }}</span
>
<!-- <i class="arrow" :class="{ expanded: group.expanded }"></i> -->
<span style="font-size: 22.5px">{{ group.deviceName }}{{ group.channels.length }}</span>
</div>
</div>
<div class="group-content" v-show="group.expanded">
<div
v-for="point in group.points"
:key="point.id"
class="point-item"
:class="{ active: selectedPoints.some((p) => p.id === point.id) }"
@click="togglePoint(point)"
>
<div class="group-content" v-show="group.channels">
<div v-for="(point, vic) in group.channels" :key="point.channelCode" class="point-item"
:class="{ active: selectedPoints.some((p) => p.channelCode === point.channelCode) }"
@click="togglePoint(point)">
<div class="point-info">
<span class="point-name">{{ point.name }}</span>
<span class="point-name">{{ point.channelName }}</span>
<div class="status-wrapper">
<span
class="status-indicator"
:class="point.status === '正常' ? 'normal' : 'warning'"
></span>
<span
class="point-status"
:class="point.status === '正常' ? 'normal' : 'warning'"
>
<span class="status-indicator" :class="point.status === 1 ? 'normal' : 'warning'"></span>
<span class="point-status" :class="point.status === 1 ? 'normal' : 'warning'">
{{ point.status }}
</span>
</div>
@ -186,12 +203,8 @@ const togglePoint = (point: any) => {
<!-- 右侧图像网格 - 改为固定显示六张图片 -->
<div class="monitor-grid">
<div class="fixed-grid-container">
<div
v-for="monitor in fixedRoadMonitors"
:key="monitor.id"
class="grid-item"
>
<!-- <div class="fixed-grid-container">
<div v-for="monitor in fixedRoadMonitors" :key="monitor.id" class="grid-item">
<div class="corner-decoration top-left"></div>
<div class="corner-decoration top-right"></div>
<div class="corner-decoration bottom-left"></div>
@ -200,6 +213,19 @@ const togglePoint = (point: any) => {
<img :src="monitor.image" :alt="monitor.name" />
</div>
</div>
</div> -->
<div class="fixed-grid-container">
<div v-for="(monitor, idx) in fixedRoadMonitors" :key="monitor.channelCode || monitor.id || idx"
class="grid-item">
<div class="corner-decoration top-left"></div>
<div class="corner-decoration top-right"></div>
<div class="corner-decoration bottom-left"></div>
<div class="corner-decoration bottom-right"></div>
<div class="image-container">
<video v-if="monitor.src" :src="monitor.src" controls autoplay
style="width:100%;height:300px;background:#000" />
</div>
</div>
</div>
</div>
</div>
@ -210,11 +236,11 @@ const togglePoint = (point: any) => {
width: 100%;
height: 100%;
display: flex;
background: rgba(0, 24, 65, 0.7);
// background: rgba(0, 24, 65, 0.7);
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(0, 198, 255, 0.3);
box-shadow: 0 0 15px rgba(0, 198, 255, 0.1);
// border: 1px solid rgba(0, 198, 255, 0.3);
// box-shadow: 0 0 15px rgba(0, 198, 255, 0.1);
padding: 2px;
padding: 30px;
}
@ -249,12 +275,10 @@ const togglePoint = (point: any) => {
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
45deg,
background: linear-gradient(45deg,
rgba(0, 198, 255, 0.05),
transparent,
rgba(0, 198, 255, 0.05)
);
rgba(0, 198, 255, 0.05));
animation: gradientPulse 3s ease-in-out infinite;
z-index: 0;
}
@ -785,6 +809,7 @@ const togglePoint = (point: any) => {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
@ -794,9 +819,11 @@ const togglePoint = (point: any) => {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}

View File

@ -1,23 +1,61 @@
<template>
<div class="center-container">
<div class="statistics-panel">
<div v-for="(stat, index) in statistics" :key="index" class="stat-card">
<div class="card-background"></div>
<div v-for="(stat, index) in statistics" :key="index" class="stat-card" style="position: relative;">
<div
class="box"
@mouseenter="stat.label === '服务区' && (showDropdown = true)"
@mouseleave="stat.label === '服务区' && (showDropdown = false)"
style="position: relative;"
>
<div class="icon-wrapper">
<img :src="stat.image" :alt="stat.label" />
</div>
<div class="stat-content">
<div class="stat-label">{{ stat.label }}</div>
<div class="stat-label">
{{ stat.label }}
</div>
<div class="stat-value">
<span class="number">{{ stat.value }}</span>
</div>
</div>
<!-- 只在服务区显示下拉选择 -->
<template v-if="stat.label === '服务区'">
<div
v-show="showDropdown"
class="dropdown large-dropdown"
@mouseenter="showDropdown = true"
@mouseleave="showDropdown = false"
>
<div
class="dropdown-item"
v-for="area in serviceAreas"
:key="area"
@click="selectServiceArea(area)"
>
{{ area }}
</div>
</div>
<div v-if="showServiceArea" class="map-container">
</template>
</div>
</div>
</div>
<!-- 下面弹框标题用当前选中的服务区 -->
<!-- <div v-if="showServiceArea" class="map-container">
<div class="map-title">
<div class="title-content">
<span class="title-text">南皮服务区</span>
<span class="title-text">{{ selectedServiceArea }}</span>
</div>
<div class="close-btn" @click="closeDialog">×</div>
</div>
<div class="map-con">
<RealTimeImageCenter />
</div>
</div> -->
<div v-if="showServiceArea" style="width: 5664px;" class="map-container RealTimeImage">
<div class="map-title">
<div class="title-content">
<span class="title-text">{{selectedServiceArea}}</span>
</div>
<div class="close-btn" @click="closeDialog">×</div>
</div>
@ -28,7 +66,7 @@
<div class="map-container bg-header bg-header-one" style="width: 1800px;" v-if="showDeviceInfo">
<div class="map-title">
<div class="title-content">
<span class="title-text">设备信息NO3_ZFJ12_3</span>
<span class="title-text">设备信息NO{{ deviceInfo.deviceId }}</span>
</div>
<div class="close-btn" @click="closeDeviceInfo">×</div>
</div>
@ -39,7 +77,7 @@
<div class="map-container bg-header bg-header-two" style="width: 1800px;height: 1000px;" v-if="showDeviceInfoTwo">
<div class="map-title">
<div class="title-content">
<span class="title-text">设备信息NO3_TCMS1</span>
<span class="title-text">设备信息NO{{ deviceInfo.deviceId }}</span>
</div>
<div class="close-btn" @click="closeDeviceInfo">×</div>
</div>
@ -71,6 +109,15 @@ const showDeviceInfoTwo = ref(false);
const closeDialog = () => {
showServiceArea.value = false;
};
const showDropdown = ref(false);
const serviceAreas = ["南皮服务区", "东光服务区"];
const selectedServiceArea = ref("南皮服务区");
function selectServiceArea(area) {
selectedServiceArea.value = area;
showServiceArea.value = true;
showDropdown.value = false;
}
//
const statistics = ref([
{
@ -138,7 +185,7 @@ function handleShowDeviceInfo(data) {
} else if (data.deviceTypeId === "15" || data.deviceTypeId === "53") {
showDeviceInfoTwo.value = true;
}
deviceInfoTwo.value = data;
deviceInfo.value = data;
}
const closeDeviceInfo = () => {
@ -160,6 +207,10 @@ onMounted(() => {
flex-direction: column;
align-items: center;
position: relative;
.RealTimeImage{
background-image: url("@/assets/img/eqm/fuwuqu.png");
background-size: 100% 100%;
}
.map-container.bg-header {
position: absolute;
top: 500px;
@ -168,11 +219,13 @@ onMounted(() => {
z-index: 2000;
// box-shadow: 0 8px 40px rgba(0,0,0,0.3);
}
.bg-header-one{
.bg-header-one {
background-image: url("@/assets/img/eqm/eqminfo.png");
background-size: 100% 100%;
}
.bg-header-two{
.bg-header-two {
background-image: url("@/assets/img/eqm/eqminfo2.png");
background-size: 100% 100%;
}
@ -187,6 +240,11 @@ onMounted(() => {
gap: 30px;
padding-top: 200px;
padding-bottom: 50px;
.box{
display: flex;
justify-content: space-around;
align-items: center;
}
}
.stat-card {
@ -268,7 +326,7 @@ onMounted(() => {
margin-bottom: 15px;
padding: 15px 40px;
position: relative;
border-bottom: 1px solid rgba(26, 233, 238, 0.2);
// border-bottom: 1px solid rgba(26, 233, 238, 0.2);
height: 150px;
background: repeating-linear-gradient(-65deg,
rgba(15, 43, 89, 0.3) 0px,
@ -362,4 +420,30 @@ onMounted(() => {
}
}
.dropdown {
position: absolute;
right: 0;
bottom: -190px;
background: #112a44;
border: 1px solid #1ae9ee;
border-radius: 6px;
z-index: 100;
min-width: 220px;
min-height: 120px;
box-shadow: 0 4px 16px rgba(0,0,0,0.25);
padding: 16px 0;
.dropdown-item {
padding: 20px 32px;
font-size: 28px;
color: #fff;
cursor: pointer;
text-align: left;
&:hover {
background: #1ae9ee;
color: #112a44;
}
}
}
</style>

View File

@ -42,9 +42,9 @@ const weather = [
<!--<div class="youjuxing"></div> -->
<!-- <div class="guang"></div> -->
<div class="d-flex jc-center">
<div class="title">
<!-- <div class="title">
<span class="title-text"></span>
</div>
</div> -->
</div>
<div class="timers">
<span>admin</span>