Compare commits

..

No commits in common. "35d22fffb947ef1806a00940201d0958ef3ae2d5" and "b7c1a2e23165413c8e8b0286f36b26f62899d13d" have entirely different histories.

37 changed files with 742 additions and 1742 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -87,9 +87,7 @@
.f3 { .f3 {
flex: 3; flex: 3;
} }
.mt_5{
margin-top: 5px;
}
.mt_10 { .mt_10 {
margin-top: 10px; margin-top: 10px;
} }

View File

@ -16,7 +16,7 @@
</div> </div>
</div> </div>
<!-- 气象预警监测表格 --> <!-- 气象预警监测表格 -->
<div class="weather-warning-wrapper"> <div class="weather-warning-wrapper" style="padding-left: 6px">
<div class="weather-warning-panel"> <div class="weather-warning-panel">
<img <img
class="clear-icon" class="clear-icon"
@ -53,19 +53,14 @@
:cell-style="cellStyle" :cell-style="cellStyle"
:row-class-name="rowClassName" :row-class-name="rowClassName"
> >
<el-table-column prop="time" label="预警时间" min-width="vw(140)" /> <el-table-column prop="time" label="预警时间" min-width="140" />
<el-table-column <el-table-column prop="type" label="类型" min-width="80" align="center" />
prop="type" <el-table-column label="预警等级" min-width="100" align="center">
label="类型"
min-width="vw(80)"
align="center"
/>
<el-table-column
label="预警等级"
min-width="vw(100)"
align="center"
>
<template #default="{ row }"> <template #default="{ row }">
<!-- <span class="warning-level" :class="row.levelClass">
<i class="level-icon"></i>
{{ row.level }}
</span> -->
<div class="warning-level"> <div class="warning-level">
<img <img
:src=" :src="
@ -82,11 +77,7 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column prop="district" label="预警区县" min-width="80" />
prop="district"
label="预警区县"
min-width="vw(80)"
/>
</el-table> </el-table>
</div> </div>
</div> </div>
@ -107,14 +98,12 @@ import tunnelIconIcon from "../../assets/RiskWarning_img/隧道icon@2x.png";
import slopeIconIcon from "../../assets/RiskWarning_img/边坡icon@2x.png"; import slopeIconIcon from "../../assets/RiskWarning_img/边坡icon@2x.png";
import bridgeIconIcon from "../../assets/RiskWarning_img/桥梁icon@2x.png"; import bridgeIconIcon from "../../assets/RiskWarning_img/桥梁icon@2x.png";
import roadIconIcon from "../../assets/RiskWarning_img/线路路段icon@2x.png"; import roadIconIcon from "../../assets/RiskWarning_img/线路路段icon@2x.png";
import teamIconIcon from "../../assets/RiskWarning_img/队伍icon@2x.png";
import warningIconIcon1 from "../../assets/RiskWarning_img/风险预警icon1@2x.png"; import warningIconIcon1 from "../../assets/RiskWarning_img/风险预警icon1@2x.png";
import tunnelIconIcon1 from "../../assets/RiskWarning_img/隧道icon1@2x.png"; import tunnelIconIcon1 from "../../assets/RiskWarning_img/隧道icon1@2x.png";
import slopeIconIcon1 from "../../assets/RiskWarning_img/边坡icon1@2x.png"; import slopeIconIcon1 from "../../assets/RiskWarning_img/边坡icon1@2x.png";
import bridgeIconIcon1 from "../../assets/RiskWarning_img/桥梁icon1@2x.png"; import bridgeIconIcon1 from "../../assets/RiskWarning_img/桥梁icon1@2x.png";
import roadIconIcon1 from "../../assets/RiskWarning_img/线路路段icon1@2x.png"; import roadIconIcon1 from "../../assets/RiskWarning_img/线路路段icon1@2x.png";
import teamIconIcon1 from "../../assets/RiskWarning_img/队伍icon1@2x.png";
const activeIndex = ref(0); const activeIndex = ref(0);
@ -154,13 +143,6 @@ const menuItems = [
icon: roadIconIcon, icon: roadIconIcon,
icon1: roadIconIcon1, icon1: roadIconIcon1,
}, },
{
label: "队伍",
icon: "icon-team",
iconClass: "team",
icon: teamIconIcon,
icon1: teamIconIcon1,
},
]; ];
// //
@ -223,15 +205,15 @@ const filteredData = computed(() => {
// el-table // el-table
const headerCellStyle = () => ({ const headerCellStyle = () => ({
background: "#17466F", background: "transparent",
color: "rgba(255, 255, 255, 0.6)", color: "rgba(255, 255, 255, 0.6)",
fontWeight: "normal", fontWeight: "normal",
borderBottom: "1px solid rgba(64, 169, 255, 0.2)", borderBottom: "1px solid rgba(64, 169, 255, 0.2)",
padding: "5px 20px", padding: "10px 8px",
}); });
const cellStyle = () => ({ const cellStyle = () => ({
background: "#142E49", background: "transparent",
color: "rgba(255, 255, 255, 0.9)", color: "rgba(255, 255, 255, 0.9)",
borderBottom: "1px solid rgba(64, 169, 255, 0.1)", borderBottom: "1px solid rgba(64, 169, 255, 0.1)",
padding: "5px 5px", padding: "5px 5px",
@ -250,12 +232,7 @@ const scrollStep = 1; // 每次滚动像素
// //
const hasFilter = computed(() => { const hasFilter = computed(() => {
return ( return filters.value.red || filters.value.blue || filters.value.orange || filters.value.yellow;
filters.value.red ||
filters.value.blue ||
filters.value.orange ||
filters.value.yellow
);
}); });
// //
@ -265,9 +242,7 @@ const startAutoScroll = () => {
} }
if (!isScrolling.value || hasFilter.value) return; if (!isScrolling.value || hasFilter.value) return;
const tableBody = document.querySelector( const tableBody = document.querySelector('.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap');
".weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap",
);
if (!tableBody) return; if (!tableBody) return;
scrollTimer.value = setInterval(() => { scrollTimer.value = setInterval(() => {
@ -292,9 +267,7 @@ const stopAutoScroll = () => {
// //
const resetScrollToTop = () => { const resetScrollToTop = () => {
const tableBody = document.querySelector( const tableBody = document.querySelector('.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap');
".weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap",
);
if (tableBody) { if (tableBody) {
tableBody.scrollTop = 0; tableBody.scrollTop = 0;
} }
@ -332,24 +305,20 @@ onMounted(() => {
nextTick(() => { nextTick(() => {
startAutoScroll(); startAutoScroll();
// //
const tableContainer = document.querySelector( const tableContainer = document.querySelector('.weather-warning-panel .table-container');
".weather-warning-panel .table-container",
);
if (tableContainer) { if (tableContainer) {
tableContainer.addEventListener("mouseenter", handleMouseEnter); tableContainer.addEventListener('mouseenter', handleMouseEnter);
tableContainer.addEventListener("mouseleave", handleMouseLeave); tableContainer.addEventListener('mouseleave', handleMouseLeave);
} }
}); });
}); });
onUnmounted(() => { onUnmounted(() => {
stopAutoScroll(); stopAutoScroll();
const tableContainer = document.querySelector( const tableContainer = document.querySelector('.weather-warning-panel .table-container');
".weather-warning-panel .table-container",
);
if (tableContainer) { if (tableContainer) {
tableContainer.removeEventListener("mouseenter", handleMouseEnter); tableContainer.removeEventListener('mouseenter', handleMouseEnter);
tableContainer.removeEventListener("mouseleave", handleMouseLeave); tableContainer.removeEventListener('mouseleave', handleMouseLeave);
} }
}); });
</script> </script>
@ -365,30 +334,27 @@ onUnmounted(() => {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: vw(10);
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
//
@media (max-width: 1366px) { @media (max-width: 1366px) {
padding: vw(8); padding: 8px;
} }
@media (max-width: 1024px) { @media (max-width: 1024px) {
padding: vw(6); padding: 6px;
} }
} }
.nav-menu { .nav-menu {
width: vw(50); width: vw(50);
min-width: vw(40); min-width: 40px;
height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: end; justify-content: end;
align-items: center; align-items: center;
gap: vw(5); gap: vw(5);
z-index: 2;
position: absolute;
bottom: 0;
left: 0;
.nav-item { .nav-item {
display: flex; display: flex;
@ -412,12 +378,12 @@ onUnmounted(() => {
.nav-icon-box { .nav-icon-box {
width: vw(50); width: vw(50);
height: vw(50); height: vw(50);
min-width: vw(36); min-width: 36px;
min-height: vw(36); min-height: 36px;
margin-bottom: vw(5); margin-bottom: vw(5);
background: rgba(64, 169, 255, 0.1); background: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: vw(8); border-radius: 8px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -425,8 +391,8 @@ onUnmounted(() => {
img { img {
width: vw(50); width: vw(50);
height: vw(50); height: vw(50);
min-width: vw(32); min-width: 32px;
min-height: vw(32); min-height: 32px;
} }
i { i {
@ -474,48 +440,57 @@ onUnmounted(() => {
// //
.weather-warning-wrapper { .weather-warning-wrapper {
flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;
width: 92%; width: 90%;
height: 50%;
position: absolute;
z-index: 2;
right: 0px;
bottom: 0px;
} }
// //
.weather-warning-panel { .weather-warning-panel {
// border-radius: vw(8); height: 50%;
background: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 8px;
padding: vw(15);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; position: relative;
.clear-icon { .clear-icon {
position: absolute; position: absolute;
top: vw(-50); top: vw(-50);
right: 0px; right: 0px;
width: vw(40) !important; width: vw(40) !important;
height: vw(40) !important; height: vw(40) !important;
min-width: vw(28); min-width: 28px;
min-height: vw(28); min-height: 28px;
} }
.panel-header { .panel-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
background-image: url("../../assets/RiskWarning_img/二级标题栏bg1@2x.png"); margin-bottom: vw(15);
background-size: 100% 100%;
background-position: left top;
padding: vw(15);
.header-title { .header-title {
font-size: vw(18); font-size: vw(18);
font-weight: 500; font-weight: bold;
color: #fff; color: #40a9ff;
position: relative; position: relative;
padding-left: vw(12);
&::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: vw(4);
height: vw(16);
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
border-radius: 2px;
}
} }
.filter-tags { .filter-tags {
@ -531,8 +506,8 @@ onUnmounted(() => {
input { input {
width: vw(14); width: vw(14);
height: vw(14); height: vw(14);
min-width: vw(12); min-width: 12px;
min-height: vw(12); min-height: 12px;
accent-color: #40a9ff; accent-color: #40a9ff;
} }
@ -561,7 +536,6 @@ onUnmounted(() => {
} }
.table-container { .table-container {
background: rgb(20, 46, 74, 0.95);
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
@ -592,28 +566,10 @@ onUnmounted(() => {
.el-table__header-wrapper { .el-table__header-wrapper {
background: transparent; background: transparent;
th.el-table__cell {
background: transparent;
font-size: vw(14);
color: rgba(255, 255, 255, 0.6);
padding: vw(10) vw(8);
}
} }
.el-table__body-wrapper { .el-table__body-wrapper {
background: transparent; background: transparent;
td.el-table__cell {
background: transparent;
font-size: vw(12);
color: rgba(255, 255, 255, 0.9);
padding: vw(5) vw(5);
}
&::-webkit-scrollbar {
display: none !important;
}
} }
tr { tr {
@ -623,17 +579,33 @@ onUnmounted(() => {
background: rgba(64, 169, 255, 0.05) !important; background: rgba(64, 169, 255, 0.05) !important;
} }
} }
th.el-table__cell {
background: transparent;
}
td.el-table__cell {
background: transparent;
}
} }
.warning-level { .warning-level {
// display: inline-flex;
// align-items: center;
// gap: 5px;
// padding: 4px 10px;
// border-radius: 4px;
// font-size: 12px;
// width: 15px;
// height: 15px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
img { img {
width: vw(15); width: vw(15);
height: vw(15); height: vw(15);
min-width: vw(10); min-width: 10px;
min-height: vw(10); min-height: 10px;
} }
// .level-icon { // .level-icon {

View File

@ -13,382 +13,128 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from "vue"; import { ref, onMounted, onUnmounted } from 'vue'
import axios from 'axios';
const mapContainer = ref(null); const mapContainer = ref(null)
const loading = ref(false); const loading = ref(false)
const error = ref(null); const error = ref(null)
let mapInstance = null; let mapInstance = null
let geoJsonLayer = null;
// emits // GeoJSON API
const emit = defineEmits(["districtClick"]); const GEOJSON_URL = 'https://geo.datav.aliyun.com/areas_v3/bound/500000_full.json'
//
const selectedDistrict = ref(null);
let selectedLayer = null;
// GeoJSON API - 使
const GEOJSON_URL =
"https://geo.datav.aliyun.com/areas_v3/bound/500000_full.json";
// //
const loadMapData = async () => { const loadMapData = async () => {
loading.value = true; loading.value = true
error.value = null; error.value = null
try { try {
//
//
const response = await fetch(GEOJSON_URL) const response = await fetch(GEOJSON_URL)
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`) throw new Error(`HTTP error! status: ${response.status}`)
} }
const geoJsonData = await response.json() const geoJsonData = await response.json()
// //
// const response = await axios.get('/aliyun-geo/bound/500000_full.json');
// const geoJsonData = response.data;
// if (!geoJsonData) {
// throw new Error('');
// }
// //
processDistrictMerge(geoJsonData);
initMap(geoJsonData) initMap(geoJsonData)
} catch (err) { } catch (err) {
console.error("加载地图数据失败:", err); console.error('加载地图数据失败:', err)
error.value = "地图数据加载失败,请检查网络连接"; error.value = '地图数据加载失败,请检查网络连接'
} finally { } finally {
loading.value = false; loading.value = false
} }
};
//
const processDistrictMerge = (geoJsonData) => {
if (!geoJsonData || !geoJsonData.features) return;
//
const yubeiIndex = geoJsonData.features.findIndex(
(f) => f.properties && f.properties.name === "渝北区",
);
const jiangbeiIndex = geoJsonData.features.findIndex(
(f) => f.properties && f.properties.name === "江北区",
);
//
if (yubeiIndex !== -1 && jiangbeiIndex !== -1) {
const yubeiFeature = geoJsonData.features[yubeiIndex];
const jiangbeiFeature = geoJsonData.features[jiangbeiIndex];
//
const liangjiangFeature = JSON.parse(JSON.stringify(yubeiFeature));
liangjiangFeature.properties.name = "两江新区";
liangjiangFeature.properties.adcode = "500006"; // 使
// MultiPolygon
if (
yubeiFeature.geometry.type === "MultiPolygon" &&
jiangbeiFeature.geometry.type === "MultiPolygon"
) {
liangjiangFeature.geometry.coordinates = [
...yubeiFeature.geometry.coordinates,
...jiangbeiFeature.geometry.coordinates,
];
} else if (
yubeiFeature.geometry.type === "Polygon" &&
jiangbeiFeature.geometry.type === "Polygon"
) {
liangjiangFeature.geometry.type = "MultiPolygon";
liangjiangFeature.geometry.coordinates = [
[yubeiFeature.geometry.coordinates],
[jiangbeiFeature.geometry.coordinates],
];
} }
//
geoJsonData.features.splice(Math.max(yubeiIndex, jiangbeiIndex), 1);
geoJsonData.features.splice(Math.min(yubeiIndex, jiangbeiIndex), 1);
//
geoJsonData.features.push(liangjiangFeature);
console.log("已合并渝北区和江北区为两江新区");
}
};
//
const getCentroid = (coordinates) => {
let sumLat = 0;
let sumLng = 0;
let count = 0;
const processCoordinates = (coords) => {
if (typeof coords[0] === "number") {
// [lng, lat]
sumLng += coords[0];
sumLat += coords[1];
count++;
} else if (Array.isArray(coords[0])) {
//
coords.forEach(processCoordinates);
}
};
processCoordinates(coordinates);
return count > 0 ? [sumLat / count, sumLng / count] : null;
};
// //
const initMap = (geoJsonData) => { const initMap = (geoJsonData) => {
if (!mapContainer.value) return; if (!mapContainer.value) return
try { try {
// //
if (mapInstance) { if (mapInstance) {
mapInstance.remove(); mapInstance.remove()
} }
// //
mapInstance = new window.L.Map(mapContainer.value, { mapInstance = new window.L.Map(mapContainer.value, {
center: [29.563, 106.551], // center: [29.563, 106.551], //
zoom: 7, zoom: 8,
minZoom: 6, minZoom: 7,
maxZoom: 18, maxZoom: 18,
zoomControl: false, zoomControl: false,
attributionControl: false, attributionControl: false
}); })
// - 使 //
const tileLayer = new window.L.TileLayer( const tileLayer = new window.L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png", attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
{ })
attribution: mapInstance.addLayer(tileLayer)
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
subdomains: "abcd",
maxZoom: 19,
},
);
mapInstance.addLayer(tileLayer);
// GeoJSON // GeoJSON
geoJsonLayer = new window.L.GeoJSON(geoJsonData, { const geoJsonLayer = new window.L.GeoJSON(geoJsonData, {
style: (feature) => ({ style: {
fillColor: "#1890ff", fillColor: '#1E3A8A',
weight: 1.5, weight: 2,
opacity: 0.6, opacity: 0.8,
color: "#40a9ff", color: '#3B82F6',
fillOpacity: 0.15, fillOpacity: 0.3
}), },
onEachFeature: (feature, layer) => { onEachFeature: (feature, layer) => {
if (feature.properties && feature.properties.name) { if (feature.properties && feature.properties.name) {
//
layer.on("click", (e) => {
//
if (selectedLayer) {
selectedLayer.setStyle({
fillColor: "#1890ff",
fillOpacity: 0.15,
weight: 1.5,
color: "#40a9ff",
});
}
//
layer.setStyle({
fillColor: "#ff4d4f",
fillOpacity: 0.6,
weight: 2.5,
color: "#ff7875",
});
selectedLayer = layer;
selectedDistrict.value = feature.properties.name;
//
emit("districtClick", {
name: feature.properties.name,
feature: feature,
latlng: e.latlng,
});
//
mapInstance.panTo(e.latlng, { animate: true, duration: 0.5 });
});
//
layer.on("mouseover", () => {
layer.setStyle({
fillColor: "#1890ff",
fillOpacity: 0.4,
weight: 2,
color: "#69c0ff",
});
});
layer.on("mouseout", () => {
layer.setStyle({
fillColor: "#1890ff",
fillOpacity: 0.15,
weight: 1.5,
color: "#40a9ff",
});
});
// popup
layer.bindPopup(`<div class="map-popup"> layer.bindPopup(`<div class="map-popup">
<strong>${feature.properties.name}</strong> <strong>${feature.properties.name}</strong>
</div>`); </div>`)
}
},
});
mapInstance.addLayer(geoJsonLayer);
//
geoJsonData.features.forEach((feature) => {
if (feature.properties && feature.properties.name) {
let centroid;
if (feature.geometry.type === "Polygon") {
centroid = getCentroid(feature.geometry.coordinates);
} else if (feature.geometry.type === "MultiPolygon") {
//
centroid = getCentroid(feature.geometry.coordinates[0]);
}
if (centroid) {
const label = window.L.divIcon({
className: "district-label",
html: `<div class="label-content">${feature.properties.name}</div>`,
iconSize: [80, 30],
iconAnchor: [40, 15],
});
const marker = window.L.marker(centroid, { icon: label });
marker.on("click", (e) => {
//
if (selectedLayer) {
selectedLayer.setStyle({
fillColor: "#1E3A8A",
fillOpacity: 0.3,
weight: 2,
});
}
//
geoJsonLayer.eachLayer((layer) => {
if (
layer.feature &&
layer.feature.properties.name === feature.properties.name
) {
layer.setStyle({
fillColor: "#ff4d4f",
fillOpacity: 0.6,
weight: 2.5,
color: "#ff7875",
});
selectedLayer = layer;
selectedDistrict.value = feature.properties.name;
}
});
//
emit("districtClick", {
name: feature.properties.name,
feature: feature,
latlng: e.latlng,
});
//
mapInstance.panTo(e.latlng, { animate: true, duration: 0.5 });
});
mapInstance.addLayer(marker);
} }
} }
}); })
mapInstance.addLayer(geoJsonLayer)
// //
mapInstance.fitBounds(geoJsonLayer.getBounds()); mapInstance.fitBounds(geoJsonLayer.getBounds())
} catch (err) { } catch (err) {
console.error("初始化地图失败:", err); console.error('初始化地图失败:', err)
error.value = "地图初始化失败"; error.value = '地图初始化失败'
}
} }
};
// //
onMounted(() => { onMounted(() => {
// Leaflet // Leaflet
if (typeof window.L === "undefined") { if (typeof window.L === 'undefined') {
// Leaflet CSSJS // Leaflet CSSJS
const link = document.createElement("link"); const link = document.createElement('link')
link.rel = "stylesheet"; link.rel = 'stylesheet'
link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"; link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css'
link.integrity = "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="; link.integrity = 'sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY='
link.crossOrigin = ""; link.crossOrigin = ''
document.head.appendChild(link); document.head.appendChild(link)
const script = document.createElement("script"); const script = document.createElement('script')
script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"; script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'
script.integrity = "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="; script.integrity = 'sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo='
script.crossOrigin = ""; script.crossOrigin = ''
script.onload = loadMapData; script.onload = loadMapData
document.head.appendChild(script); document.head.appendChild(script)
} else { } else {
loadMapData(); loadMapData()
} }
}); })
// //
onUnmounted(() => { onUnmounted(() => {
if (mapInstance) { if (mapInstance) {
mapInstance.remove(); mapInstance.remove()
mapInstance = null; mapInstance = null
} }
}); })
</script> </script>
<style lang="scss">
// Leaflet
.district-label {
background: transparent !important;
border: none !important;
.label-content {
background: transparent;
color: #fff;
padding: vw(4) vw(8);
border-radius: vw(2);
font-weight: 500;
text-align: center;
white-space: nowrap;
text-shadow:
0 1px 3px rgba(0, 0, 0, 0.8),
0 0 2px rgba(0, 0, 0, 0.5);
letter-spacing: 0.5px;
cursor: pointer;
width: fit-content;
transition: all 0.3s;
&:hover {
color: #40a9ff;
text-shadow: 0 0 10px rgba(64, 169, 255, 0.8);
transform: scale(1.05);
}
}
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
// -
@function vw($px) {
@return calc($px / 1920 * 100vw);
}
.chongqing-map-container { .chongqing-map-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -417,47 +163,43 @@ onUnmounted(() => {
} }
.loading-spinner { .loading-spinner {
width: vw(40); width: 40px;
height: vw(40); height: 40px;
border: vw(4) solid #3b82f6; border: 4px solid #3B82F6;
border-top: vw(4) solid transparent; border-top: 4px solid transparent;
border-radius: 50%; border-radius: 50%;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
margin-bottom: vw(10); margin-bottom: 10px;
} }
.loading-text { .loading-text {
color: #fff; color: #fff;
font-size: vw(14); font-size: 14px;
} }
.error-text { .error-text {
color: #ff6b6b; color: #ff6b6b;
font-size: vw(14); font-size: 14px;
margin-bottom: vw(10); margin-bottom: 10px;
} }
.retry-btn { .retry-btn {
background: #3b82f6; background: #3B82F6;
color: white; color: white;
border: none; border: none;
padding: vw(8) vw(16); padding: 8px 16px;
border-radius: vw(4); border-radius: 4px;
cursor: pointer; cursor: pointer;
font-size: vw(12); font-size: 12px;
&:hover { &:hover {
background: #2563eb; background: #2563EB;
} }
} }
@keyframes spin { @keyframes spin {
0% { 0% { transform: rotate(0deg); }
transform: rotate(0deg); 100% { transform: rotate(360deg); }
}
100% {
transform: rotate(360deg);
}
} }
// Leaflet // Leaflet
@ -465,36 +207,17 @@ onUnmounted(() => {
background: #0f1c2e !important; background: #0f1c2e !important;
.leaflet-popup-content-wrapper { .leaflet-popup-content-wrapper {
background: rgba(24, 144, 255, 0.95); background: rgba(64, 169, 255, 0.9);
border-radius: vw(4); border-radius: 4px;
padding: vw(6) vw(12);
min-width: vw(80);
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
.map-popup { .map-popup {
color: #fff; color: #fff;
font-size: vw(12); font-size: 12px;
text-align: center;
margin: 0;
padding: 0;
font-weight: 500;
} }
} }
.leaflet-popup-tip { .leaflet-popup-tip {
background: rgba(24, 144, 255, 0.95); background: rgba(64, 169, 255, 0.9);
} }
.leaflet-popup-content {
width: max-content !important;
margin: vw(10) 10px vw(10) 0;
line-height: 1.3;
}
}
//
:deep(.leaflet-interactive) {
transition: all 0.3s;
cursor: pointer;
} }
</style> </style>

View File

@ -160,8 +160,7 @@ watch(
} }
.ai-dialog { .ai-dialog {
width: 80vw; width: 1000px;
max-width: 1000px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;

View File

@ -51,14 +51,16 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 50px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 80px">行政区域</div>
:key="index" <div class="th" style="width: 80px">线路编号</div>
class="th" <div class="th" style="width: 100px">起止桩号</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 100px">路况位置</div>
> <div class="th" style="width: 140px">发生时间</div>
{{ column.label }} <div class="th" style="width: 80px">线路编号</div>
</div> <div class="th" style="width: 80px">类型</div>
<div class="th" style="width: 100px">管控措施</div>
<div class="th" style="flex: 1">操作</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -120,7 +122,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue"; import { Close } from "@element-plus/icons-vue";
import { regionOptions, typeOptions, controlMeasureOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -139,26 +140,27 @@ const filterForm = ref({
}); });
// //
// index.js const regionOptions = ref([
{ label: "巫溪县", value: "巫溪县" },
{ label: "万州区", value: "万州区" },
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "渝中区", value: "渝中区" },
]);
// //
// index.js const typeOptions = ref([
{ label: "边坡坍塌", value: "边坡坍塌" },
{ label: "路面塌陷", value: "路面塌陷" },
{ label: "桥梁损坏", value: "桥梁损坏" },
{ label: "隧道事故", value: "隧道事故" },
]);
// //
// index.js const controlMeasureOptions = ref([
{ label: "全幅封闭", value: "全幅封闭" },
// { label: "半幅封闭", value: "半幅封闭" },
const tableColumns = ref([ { label: "正常通行", value: "正常通行" },
{ label: "序号", width: "50px" }, { label: "限制通行", value: "限制通行" },
{ label: "行政区域", width: "80px" },
{ label: "线路编号", width: "80px" },
{ label: "起止桩号", width: "100px" },
{ label: "路况位置", width: "100px" },
{ label: "发生时间", width: "140px" },
{ label: "线路编号", width: "80px" },
{ label: "类型", width: "80px" },
{ label: "管控措施", width: "100px" },
{ label: "操作", flex: "1" },
]); ]);
// //
@ -312,8 +314,7 @@ watch(
} }
.clearance-dialog { .clearance-dialog {
width: 80vw; width: 1000px;
max-width: 1000px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -364,8 +365,7 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
gap: 12px; gap: 24px;
flex-wrap: wrap;
} }
.filter-item { .filter-item {

View File

@ -88,30 +88,12 @@ const handleOverlayClick = () => {
} }
.confirm-dialog { .confirm-dialog {
width: 80vw; width: 360px;
max-width: 400px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 8px; border-radius: 8px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
overflow: hidden; overflow: hidden;
animation: dialogSlideIn 0.3s ease-out;
@media (max-width: 768px) {
width: 90vw;
max-width: 90vw;
}
}
@keyframes dialogSlideIn {
from {
opacity: 0;
transform: scale(0.8) translateY(-50px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
} }
// //
@ -127,23 +109,18 @@ const handleOverlayClick = () => {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
color: #fff; color: #fff;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.close-btn { .close-btn {
width: 19px; width: 24px;
height: 19px; height: 24px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
cursor: pointer; cursor: pointer;
font-size: 13px; font-size: 16px;
transition: color 0.3s; transition: color 0.3s;
flex-shrink: 0;
&:hover { &:hover {
color: #fff; color: #fff;
@ -155,16 +132,12 @@ const handleOverlayClick = () => {
.dialog-content { .dialog-content {
padding: 24px 20px; padding: 24px 20px;
text-align: center; text-align: center;
max-height: 40vh;
overflow-y: auto;
.confirm-message { .confirm-message {
font-size: 16px; font-size: 14px;
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
line-height: 1.6; line-height: 1.6;
margin: 0; margin: 0;
word-wrap: break-word;
word-break: break-all;
} }
} }
@ -174,20 +147,16 @@ const handleOverlayClick = () => {
justify-content: center; justify-content: center;
gap: 16px; gap: 16px;
padding: 0 20px 20px; padding: 0 20px 20px;
flex-wrap: wrap;
.btn-cancel { .btn-cancel {
min-width: 80px; min-width: 80px;
height: 26px; height: 32px;
padding: 0 16px;
background-color: transparent; background-color: transparent;
border: 1px solid rgba(64, 169, 255, 0.4); border: 1px solid rgba(64, 169, 255, 0.4);
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
font-size: 10px; font-size: 13px;
border-radius: 4px; border-radius: 4px;
transition: all 0.3s; transition: all 0.3s;
flex: 1;
min-flex: 64px;
&:hover { &:hover {
background-color: rgba(64, 169, 255, 0.1); background-color: rgba(64, 169, 255, 0.1);
@ -198,16 +167,13 @@ const handleOverlayClick = () => {
.btn-confirm { .btn-confirm {
min-width: 80px; min-width: 80px;
height: 26px; height: 32px;
padding: 0 16px;
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%); background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border: none; border: none;
color: #fff; color: #fff;
font-size: 10px; font-size: 13px;
border-radius: 4px; border-radius: 4px;
transition: all 0.3s; transition: all 0.3s;
flex: 1;
min-flex: 64px;
&:hover { &:hover {
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%); background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);

View File

@ -40,14 +40,12 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">行政区域</div>
:key="index" <div class="th" style="width: 200px">驻地名称</div>
class="th" <div class="th" style="width: 200px">所属项目</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 80px">驻地人数</div>
> <div class="th" style="flex: 1">驻地风险等级</div>
{{ column.label }}
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -103,7 +101,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue"; import { Close } from "@element-plus/icons-vue";
import { regionOptions, riskLevelOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -121,19 +118,19 @@ const filterForm = ref({
}); });
// //
// index.js const regionOptions = ref([
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "万州区", value: "万州区" },
{ label: "渝中区", value: "渝中区" },
{ label: "江北区", value: "江北区" },
]);
// //
// index.js const riskLevelOptions = ref([
{ label: "Ⅰ级", value: "Ⅰ级" },
// { label: "Ⅱ级", value: "Ⅱ级" },
const tableColumns = ref([ { label: "Ⅲ级", value: "Ⅲ级" },
{ label: "序号", width: "60px" }, { label: "Ⅳ级", value: "Ⅳ级" },
{ label: "行政区域", width: "100px" },
{ label: "驻地名称", width: "200px" },
{ label: "所属项目", width: "200px" },
{ label: "驻地人数", width: "80px" },
{ label: "驻地风险等级", flex: "1" },
]); ]);
// //
@ -270,8 +267,7 @@ watch(
} }
.control-dialog { .control-dialog {
width: 80vw; width: 900px;
max-width: 900px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -322,8 +318,7 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
gap: 12px; gap: 24px;
flex-wrap: wrap;
} }
.filter-item { .filter-item {

View File

@ -40,14 +40,13 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 50px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">区县/镇街</div>
:key="index" <div class="th" style="width: 80px">姓名</div>
class="th" <div class="th" style="width: 120px">电话</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 100px">类型</div>
> <div class="th" style="width: 140px">角色</div>
{{ column.label }} <div class="th" style="flex: 1">调度时间</div>
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -94,7 +93,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue"; import { Close } from "@element-plus/icons-vue";
import { regionOptions, typeOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -112,20 +110,19 @@ const filterForm = ref({
}); });
// //
// index.js const regionOptions = ref([
{ label: "柏梓镇", value: "柏梓镇" },
{ label: "万州区", value: "万州区" },
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "渝中区", value: "渝中区" },
]);
// //
// index.js const typeOptions = ref([
{ label: "交通主管部门", value: "交通主管部门" },
// { label: "公路机构", value: "公路机构" },
const tableColumns = ref([ { label: "养护站", value: "养护站" },
{ label: "序号", width: "50px" }, { label: "护路员", value: "护路员" },
{ label: "区县/镇街", width: "100px" },
{ label: "姓名", width: "80px" },
{ label: "电话", width: "120px" },
{ label: "类型", width: "100px" },
{ label: "角色", width: "140px" },
{ label: "调度时间", flex: "1" },
]); ]);
// //
@ -255,8 +252,7 @@ watch(
} }
.dispatch-detail-dialog { .dispatch-detail-dialog {
width: 80vw; width: 900px;
max-width: 900px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -307,8 +303,7 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
gap: 12px; gap: 24px;
flex-wrap: wrap;
} }
.filter-item { .filter-item {

View File

@ -29,14 +29,10 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 120px">行政区域</div>
:key="index" <div class="th" style="width: 100px">调度数</div>
class="th" <div class="th" style="flex: 1">最近调度时间</div>
:style="{ width: column.width, flex: column.flex || 'none' }"
>
{{ column.label }}
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -82,7 +78,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue"; import { Close } from "@element-plus/icons-vue";
import { regionOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -99,14 +94,11 @@ const filterForm = ref({
}); });
// //
// index.js const regionOptions = ref([
{ label: "重庆市", value: "重庆市" },
// { label: "万州区", value: "万州区" },
const tableColumns = ref([ { label: "沙坪坝区", value: "沙坪坝区" },
{ label: "序号", width: "60px" }, { label: "渝中区", value: "渝中区" },
{ label: "行政区域", width: "120px" },
{ label: "调度数", width: "100px" },
{ label: "最近调度时间", flex: "1" },
]); ]);
// //
@ -229,8 +221,7 @@ watch(
} }
.dispatch-dialog { .dispatch-dialog {
width: 80vw; width: 700px;
max-width: 700px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -281,8 +272,7 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
gap: 12px; gap: 24px;
flex-wrap: wrap;
} }
.filter-item { .filter-item {

View File

@ -243,8 +243,7 @@ watch(
} }
.event-dialog { .event-dialog {
width: 80vw; width: 700px;
max-width: 700px;
max-height: 85vh; max-height: 85vh;
overflow-y: auto; overflow-y: auto;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);

View File

@ -234,8 +234,7 @@ watch(
} }
.impact-detail-dialog { .impact-detail-dialog {
width: 80vw; width: 650px;
max-width: 650px;
max-height: 90vh; max-height: 90vh;
overflow-y: auto; overflow-y: auto;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);

View File

@ -8,59 +8,32 @@
<el-icon><Close /></el-icon> <el-icon><Close /></el-icon>
</div> </div>
</div> </div>
<div></div>
<!-- 统计卡片 -->
<div class="stats-cards">
<div class="stat-card">
<div class="stat-label">影响桥梁</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响边坡</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响隧道</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响项目</div>
<div class="stat-value">2933</div>
</div>
</div>
<!-- 筛选区域 --> <!-- 筛选区域 -->
<div class="filter-section"> <div class="filter-section">
<div class="filter-row"> <div class="filter-row">
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.pointType" placeholder="影响点类型" class="filter-select"> <el-select v-model="filterForm.pointType" placeholder="影响点类型" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in pointTypeOptions" <el-option label="边坡" value="slope" />
:key="option.value" <el-option label="桥梁" value="bridge" />
:label="option.label" <el-option label="隧道" value="tunnel" />
:value="option.value" <el-option label="路面" value="road" />
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.pointLevel" placeholder="影响点等级" class="filter-select"> <el-select v-model="filterForm.pointLevel" placeholder="影响点等级" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in pointLevelOptions" <el-option label="一般隐患" value="normal" />
:key="option.value" <el-option label="重大隐患" value="serious" />
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select"> <el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in regionOptionsWithAll" <el-option label="万州区" value="wanzhou" />
:key="option.value" <el-option label="涪陵区" value="fuling" />
:label="option.label" <el-option label="合川区" value="hechuan" />
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
@ -74,14 +47,16 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 50px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 80px">行政区域</div>
:key="index" <div class="th" style="width: 80px">影响点类型</div>
class="th" <div class="th" style="width: 180px">影响点位置</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 90px">影响点等级</div>
> <div class="th" style="width: 130px">交通主管部门负责人</div>
{{ column.label }} <div class="th" style="width: 110px">公路机构责任人</div>
</div> <div class="th" style="width: 110px">养护站负责人</div>
<div class="th" style="width: 100px">护路员</div>
<div class="th" style="width: 60px">操作</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -156,7 +131,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue"; import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import { pointTypeOptions, pointLevelOptions, regionOptionsWithAll } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -174,20 +148,6 @@ const filterForm = ref({
region: "", region: "",
}); });
//
const tableColumns = ref([
{ label: "序号", width: "50px" },
{ label: "行政区域", width: "80px" },
{ label: "影响点类型", width: "80px" },
{ label: "影响点位置", width: "180px" },
{ label: "影响点等级", width: "90px" },
{ label: "交通主管部门负责人", width: "130px" },
{ label: "公路机构责任人", width: "110px" },
{ label: "养护站负责人", width: "110px" },
{ label: "护路员", width: "100px" },
{ label: "操作", width: "60px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -313,11 +273,6 @@ watch(
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
// -
@function vw($px) {
@return calc($px / 1920 * 100vw);
}
.impact-dialog-overlay { .impact-dialog-overlay {
position: fixed; position: fixed;
top: 0; top: 0;
@ -332,12 +287,11 @@ watch(
} }
.impact-dialog { .impact-dialog {
width: 80vw; width: 1050px;
max-width: 1200px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: vw(12); border-radius: 12px;
padding: vw(24); padding: 24px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
} }
@ -347,29 +301,29 @@ watch(
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: relative; position: relative;
margin-bottom: vw(20); margin-bottom: 20px;
.header-title { .header-title {
font-size: vw(20); font-size: 20px;
font-weight: 600; font-weight: 600;
color: #fff; color: #fff;
padding: vw(8) vw(40); padding: 8px 40px;
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%); background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
border-bottom: vw(2) solid #40a9ff; border-bottom: 2px solid #40a9ff;
} }
.close-btn { .close-btn {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
width: vw(32); width: 32px;
height: vw(32); height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
cursor: pointer; cursor: pointer;
font-size: vw(20); font-size: 20px;
transition: color 0.3s; transition: color 0.3s;
&:hover { &:hover {
@ -378,69 +332,29 @@ watch(
} }
} }
//
.stats-cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: vw(16);
margin-bottom: vw(20);
.stat-card {
background: linear-gradient(135deg, rgba(30, 70, 120, 0.6) 0%, rgba(20, 50, 90, 0.8) 100%);
border: vw(2) solid rgba(64, 169, 255, 0.4);
border-radius: vw(8);
padding: vw(16) vw(20);
text-align: center;
transition: all 0.3s;
cursor: pointer;
&:hover {
border-color: rgba(64, 169, 255, 0.8);
box-shadow: 0 0 20px rgba(64, 169, 255, 0.3);
transform: translateY(-2px);
}
.stat-label {
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
margin-bottom: vw(8);
font-weight: 500;
}
.stat-value {
font-size: vw(28);
font-weight: bold;
color: #40a9ff;
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
}
}
}
// //
.filter-section { .filter-section {
margin-bottom: vw(20); margin-bottom: 20px;
.filter-row { .filter-row {
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap;
gap: 12px; gap: 12px;
} }
.filter-item { .filter-item {
.filter-select { .filter-select {
width: vw(150); width: 150px;
:deep(.el-input__wrapper) { :deep(.el-input__wrapper) {
background-color: rgba(30, 70, 120, 0.4); background-color: rgba(30, 70, 120, 0.4);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: none; box-shadow: none;
border-radius: vw(4); border-radius: 4px;
.el-input__inner { .el-input__inner {
color: #fff; color: #fff;
font-size: vw(13); font-size: 13px;
&::placeholder { &::placeholder {
color: rgba(255, 255, 255, 0.5); color: rgba(255, 255, 255, 0.5);
@ -458,10 +372,10 @@ watch(
.search-btn { .search-btn {
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%); background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border: none; border: none;
border-radius: vw(4); border-radius: 4px;
padding: 0 vw(24); padding: 0 24px;
height: vw(32); height: 32px;
font-size: vw(13); font-size: 13px;
&:hover { &:hover {
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%); background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
@ -473,17 +387,17 @@ watch(
// //
.table-section { .table-section {
background-color: rgba(30, 70, 120, 0.3); background-color: rgba(30, 70, 120, 0.3);
border-radius: vw(8); border-radius: 8px;
overflow: hidden; overflow: hidden;
margin-bottom: vw(20); margin-bottom: 20px;
.table-header { .table-header {
display: flex; display: flex;
background-color: rgba(64, 169, 255, 0.2); background-color: rgba(64, 169, 255, 0.2);
padding: vw(12) vw(16); padding: 12px 16px;
.th { .th {
font-size: vw(13); font-size: 13px;
font-weight: 500; font-weight: 500;
color: #fff; color: #fff;
text-align: center; text-align: center;
@ -496,10 +410,10 @@ watch(
.table-row { .table-row {
display: flex; display: flex;
padding: vw(12) vw(16); padding: 12px 16px;
align-items: center; align-items: center;
transition: background-color 0.3s; transition: background-color 0.3s;
min-height: vw(60); min-height: 60px;
&:hover { &:hover {
background-color: rgba(64, 169, 255, 0.1); background-color: rgba(64, 169, 255, 0.1);
@ -510,17 +424,17 @@ watch(
} }
.td { .td {
font-size: vw(12); font-size: 12px;
color: rgba(255, 255, 255, 0.85); color: rgba(255, 255, 255, 0.85);
text-align: center; text-align: center;
word-break: break-all; word-break: break-all;
padding: 0 vw(4); padding: 0 4px;
.level-tag { .level-tag {
display: inline-block; display: inline-block;
padding: vw(2) vw(8); padding: 2px 8px;
border-radius: vw(4); border-radius: 4px;
font-size: vw(11); font-size: 11px;
&.level-normal { &.level-normal {
background-color: rgba(250, 219, 95, 0.2); background-color: rgba(250, 219, 95, 0.2);
@ -538,15 +452,15 @@ watch(
.person-info { .person-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: vw(2); gap: 2px;
.person-name { .person-name {
font-size: vw(12); font-size: 12px;
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
} }
.person-phone { .person-phone {
font-size: vw(11); font-size: 11px;
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
} }
} }
@ -554,7 +468,7 @@ watch(
.detail-link { .detail-link {
color: #40a9ff; color: #40a9ff;
cursor: pointer; cursor: pointer;
font-size: vw(12); font-size: 12px;
&:hover { &:hover {
color: #69c0ff; color: #69c0ff;
@ -571,27 +485,27 @@ watch(
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
gap: vw(16); gap: 16px;
.total { .total {
font-size: vw(13); font-size: 13px;
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
} }
.page-btns { .page-btns {
display: flex; display: flex;
gap: vw(8); gap: 8px;
.page-btn { .page-btn {
min-width: vw(28); min-width: 28px;
height: vw(28); height: 28px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: rgba(64, 169, 255, 0.1); background-color: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.2); border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: vw(4); border-radius: 4px;
font-size: vw(12); font-size: 12px;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
@ -617,17 +531,17 @@ watch(
// //
.table-body::-webkit-scrollbar { .table-body::-webkit-scrollbar {
width: vw(6); width: 6px;
} }
.table-body::-webkit-scrollbar-track { .table-body::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
border-radius: vw(3); border-radius: 3px;
} }
.table-body::-webkit-scrollbar-thumb { .table-body::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%); background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
border-radius: vw(3); border-radius: 3px;
} }
.table-body::-webkit-scrollbar-thumb:hover { .table-body::-webkit-scrollbar-thumb:hover {

View File

@ -1,109 +0,0 @@
// 弹窗组件统一数据配置
// 行政区域选项
export const regionOptions = [
{ label: "重庆市", value: "重庆市" },
{ label: "万州区", value: "万州区" },
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "渝中区", value: "渝中区" },
{ label: "巫溪县", value: "巫溪县" },
{ label: "涪陵区", value: "涪陵区" },
{ label: "合川区", value: "合川区" },
{ label: "万盛区", value: "万盛区" },
{ label: "长寿区", value: "长寿区" },
{ label: "城口区", value: "城口区" },
{ label: "柏梓镇", value: "柏梓镇" },
{ label: "江北区", value: "江北区" },
];
// 类型选项
export const typeOptions = [
{ label: "边坡坍塌", value: "边坡坍塌" },
{ label: "路面塌陷", value: "路面塌陷" },
{ label: "桥梁损坏", value: "桥梁损坏" },
{ label: "隧道事故", value: "隧道事故" },
{ label: "交通主管部门", value: "交通主管部门" },
{ label: "公路机构", value: "公路机构" },
{ label: "养护站", value: "养护站" },
{ label: "护路员", value: "护路员" },
];
// 管控措施选项
export const controlMeasureOptions = [
{ label: "全幅封闭", value: "全幅封闭" },
{ label: "半幅封闭", value: "半幅封闭" },
{ label: "正常通行", value: "正常通行" },
{ label: "限制通行", value: "限制通行" },
];
// 风险等级选项
export const riskLevelOptions = [
{ label: "一级", value: "一级" },
{ label: "二级", value: "二级" },
{ label: "三级", value: "三级" },
{ label: "四级", value: "四级" },
];
// 影响点类型选项
export const pointTypeOptions = [
{ label: "全部", value: "" },
{ label: "边坡", value: "slope" },
{ label: "桥梁", value: "bridge" },
{ label: "隧道", value: "tunnel" },
{ label: "路面", value: "road" },
];
// 影响点等级选项
export const pointLevelOptions = [
{ label: "全部", value: "" },
{ label: "一般隐患", value: "normal" },
{ label: "重大隐患", value: "serious" },
];
// 是否回应选项
export const isRespondedOptions = [
{ label: "全部", value: "" },
{ label: "是", value: "yes" },
{ label: "否", value: "no" },
];
// 预警等级选项
export const warningLevelOptions = [
{ label: "全部", value: "" },
{ label: "红色预警", value: "red" },
{ label: "橙色预警", value: "orange" },
{ label: "黄色预警", value: "yellow" },
{ label: "蓝色预警", value: "blue" },
];
// 是否结束选项
export const isEndedOptions = [
{ label: "全部", value: "" },
{ label: "是", value: "yes" },
{ label: "否", value: "no" },
];
// 行政区域选项(带全部)
export const regionOptionsWithAll = [
{ label: "全部", value: "" },
{ label: "万州区", value: "wanzhou" },
{ label: "涪陵区", value: "fuling" },
{ label: "合川区", value: "hechuan" },
{ label: "万盛区", value: "wansheng" },
{ label: "长寿区", value: "changshou" },
{ label: "城口区", value: "chengkou" },
];
// 默认导出所有选项
export default {
regionOptions,
typeOptions,
controlMeasureOptions,
riskLevelOptions,
pointTypeOptions,
pointLevelOptions,
isRespondedOptions,
warningLevelOptions,
isEndedOptions,
regionOptionsWithAll,
};

View File

@ -271,8 +271,7 @@ watch(
} }
.response-dialog { .response-dialog {
width: 80vw; width: 700px;
max-width: 700px;
max-height: 90vh; max-height: 90vh;
overflow-y: auto; overflow-y: auto;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);

View File

@ -305,8 +305,7 @@ watch(
} }
.response-info-dialog { .response-info-dialog {
width: 80vw; width: 750px;
max-width: 750px;
max-height: 90vh; max-height: 90vh;
overflow-y: auto; overflow-y: auto;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);

View File

@ -52,14 +52,13 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 120px">区县/镇街</div>
:key="index" <div class="th" style="width: 100px">姓名</div>
class="th" <div class="th" style="width: 120px">电话</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="flex: 1">角色</div>
> <div class="th" style="width: 100px">职务</div>
{{ column.label }} <div class="th" style="width: 120px">操作</div>
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -136,17 +135,6 @@ const stats = ref({
village: 1099, village: 1099,
}); });
//
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "区县/镇街", width: "120px" },
{ label: "姓名", width: "100px" },
{ label: "电话", width: "120px" },
{ label: "角色", flex: "1" },
{ label: "职务", width: "100px" },
{ label: "操作", width: "120px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ id: 1, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" }, { id: 1, district: "万州区柏梓镇", name: "赵海浪", phone: "1862352068", role: "一般人员(路长履职)", position: "其他" },
@ -263,13 +251,11 @@ watch(
} }
.response-dialog { .response-dialog {
width: 70vw; width: 900px;
max-width: 700px;
max-height: 80vh;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
padding: 16px; padding: 24px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
} }
@ -279,13 +265,13 @@ watch(
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: relative; position: relative;
margin-bottom: 12px; margin-bottom: 24px;
.header-title { .header-title {
font-size: 14px; font-size: 20px;
font-weight: 600; font-weight: 600;
color: #fff; color: #fff;
padding: 4px 24px; padding: 8px 40px;
background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%); background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
border-bottom: 2px solid #40a9ff; border-bottom: 2px solid #40a9ff;
} }
@ -294,14 +280,14 @@ watch(
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
width: 24px; width: 32px;
height: 24px; height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
cursor: pointer; cursor: pointer;
font-size: 16px; font-size: 20px;
transition: color 0.3s; transition: color 0.3s;
&:hover { &:hover {
@ -313,55 +299,55 @@ watch(
// //
.stats-cards { .stats-cards {
display: flex; display: flex;
gap: 12px; gap: 20px;
margin-bottom: 12px; margin-bottom: 24px;
.stat-card { .stat-card {
flex: 1; flex: 1;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 12px;
background: linear-gradient(135deg, rgba(30, 80, 140, 0.6) 0%, rgba(20, 60, 110, 0.8) 100%); background: linear-gradient(135deg, rgba(30, 80, 140, 0.6) 0%, rgba(20, 60, 110, 0.8) 100%);
border: 1px solid rgba(64, 169, 255, 0.2); border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 4px; border-radius: 8px;
padding: 10px 12px; padding: 16px 20px;
.card-icon { .card-icon {
width: 32px; width: 48px;
height: 32px; height: 48px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: rgba(64, 169, 255, 0.15); background-color: rgba(64, 169, 255, 0.15);
border-radius: 4px; border-radius: 8px;
.stat-icon { .stat-icon {
font-size: 18px; font-size: 28px;
color: #40a9ff; color: #40a9ff;
} }
} }
.card-info { .card-info {
.card-label { .card-label {
font-size: 11px; font-size: 14px;
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
margin-bottom: 1px; margin-bottom: 4px;
} }
.card-value { .card-value {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
gap: 2px; gap: 4px;
.value-num { .value-num {
font-size: 18px; font-size: 28px;
font-weight: 700; font-weight: 700;
color: #40a9ff; color: #40a9ff;
text-shadow: 0 0 6px rgba(64, 169, 255, 0.5); text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
} }
.value-unit { .value-unit {
font-size: 10px; font-size: 13px;
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
} }
} }
@ -372,17 +358,17 @@ watch(
// //
.table-section { .table-section {
background-color: rgba(30, 70, 120, 0.3); background-color: rgba(30, 70, 120, 0.3);
border-radius: 4px; border-radius: 8px;
overflow: hidden; overflow: hidden;
margin-bottom: 12px; margin-bottom: 20px;
.table-header { .table-header {
display: flex; display: flex;
background-color: rgba(64, 169, 255, 0.2); background-color: rgba(64, 169, 255, 0.2);
padding: 8px 12px; padding: 12px 16px;
.th { .th {
font-size: 12px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #fff; color: #fff;
text-align: center; text-align: center;
@ -390,12 +376,12 @@ watch(
} }
.table-body { .table-body {
max-height: 30vh; max-height: 240px;
overflow-y: auto; overflow-y: auto;
.table-row { .table-row {
display: flex; display: flex;
padding: 10px 12px; padding: 12px 16px;
align-items: center; align-items: center;
transition: background-color 0.3s; transition: background-color 0.3s;
@ -408,23 +394,23 @@ watch(
} }
.td { .td {
font-size: 11px; font-size: 13px;
color: rgba(255, 255, 255, 0.85); color: rgba(255, 255, 255, 0.85);
text-align: center; text-align: center;
.action-btns { .action-btns {
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 8px; gap: 12px;
.action-btn { .action-btn {
width: 20px; width: 28px;
height: 20px; height: 28px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: rgba(64, 169, 255, 0.15); background-color: rgba(64, 169, 255, 0.15);
border-radius: 2px; border-radius: 4px;
color: #40a9ff; color: #40a9ff;
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
@ -445,27 +431,27 @@ watch(
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
gap: 10px; gap: 16px;
.total { .total {
font-size: 11px; font-size: 13px;
color: rgba(255, 255, 255, 0.6); color: rgba(255, 255, 255, 0.6);
} }
.page-btns { .page-btns {
display: flex; display: flex;
gap: 4px; gap: 8px;
.page-btn { .page-btn {
min-width: 24px; min-width: 32px;
height: 24px; height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: rgba(64, 169, 255, 0.1); background-color: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.2); border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 2px; border-radius: 4px;
font-size: 11px; font-size: 13px;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
@ -491,17 +477,17 @@ watch(
// //
.table-body::-webkit-scrollbar { .table-body::-webkit-scrollbar {
width: 4px; width: 8px;
} }
.table-body::-webkit-scrollbar-track { .table-body::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
border-radius: 2px; border-radius: 4px;
} }
.table-body::-webkit-scrollbar-thumb { .table-body::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%); background: linear-gradient(180deg, #40a9ff 0%, #1890ff 100%);
border-radius: 2px; border-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
} }

View File

@ -1,9 +1,5 @@
<template> <template>
<div <div v-if="visible" class="response-status-dialog-overlay" @click="handleOverlayClick">
v-if="visible"
class="response-status-dialog-overlay"
@click="handleOverlayClick"
>
<div class="response-status-dialog" @click.stop> <div class="response-status-dialog" @click.stop>
<!-- 标题栏 --> <!-- 标题栏 -->
<div class="dialog-header"> <div class="dialog-header">
@ -13,69 +9,30 @@
</div> </div>
</div> </div>
<!-- 统计卡片 -->
<div class="stats-cards">
<div class="stat-card">
<div class="stat-label">影响桥梁</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响边坡</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响隧道</div>
<div class="stat-value">2933</div>
</div>
<div class="stat-card">
<div class="stat-label">影响项目</div>
<div class="stat-value">2933</div>
</div>
</div>
<!-- 筛选区域 --> <!-- 筛选区域 -->
<div class="filter-section"> <div class="filter-section">
<div class="filter-row"> <div class="filter-row">
<div class="filter-item"> <div class="filter-item">
<el-select <el-select v-model="filterForm.pointType" placeholder="影响点类型" class="filter-select">
v-model="filterForm.pointType" <el-option label="全部" value="" />
placeholder="影响点类型" <el-option label="边坡" value="slope" />
class="filter-select" <el-option label="桥梁" value="bridge" />
> <el-option label="隧道" value="tunnel" />
<el-option <el-option label="路面" value="road" />
v-for="option in pointTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select <el-select v-model="filterForm.pointLevel" placeholder="影响点等级" class="filter-select">
v-model="filterForm.pointLevel" <el-option label="全部" value="" />
placeholder="影响点等级" <el-option label="一般隐患" value="normal" />
class="filter-select" <el-option label="重大隐患" value="serious" />
>
<el-option
v-for="option in pointLevelOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select <el-select v-model="filterForm.isResponded" placeholder="是否回应" class="filter-select">
v-model="filterForm.isResponded" <el-option label="全部" value="" />
placeholder="是否回应" <el-option label="是" value="yes" />
class="filter-select" <el-option label="否" value="no" />
>
<el-option
v-for="option in isRespondedOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
</div> </div>
@ -84,14 +41,18 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 50px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 80px">影响点类型</div>
:key="index" <div class="th" style="width: 180px">影响点位置</div>
class="th" <div class="th" style="width: 90px">影响点等级</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 60px">查次数</div>
> <div class="th" style="width: 120px">交通主管部门负责人</div>
{{ column.label }} <div class="th" style="width: 110px">公路机构责任人</div>
</div> <div class="th" style="width: 110px">养护站负责人</div>
<div class="th" style="width: 80px">护路员</div>
<div class="th" style="width: 70px">回应状态</div>
<div class="th" style="width: 110px">最新催告时间</div>
<div class="th" style="width: 50px">操作</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -102,11 +63,9 @@
> >
<div class="td" style="width: 50px">{{ item.id }}</div> <div class="td" style="width: 50px">{{ item.id }}</div>
<div class="td" style="width: 80px">{{ item.pointType }}</div> <div class="td" style="width: 80px">{{ item.pointType }}</div>
<div class="td" style="width: 150px">{{ item.pointLocation }}</div> <div class="td" style="width: 180px">{{ item.pointLocation }}</div>
<div class="td" style="width: 90px"> <div class="td" style="width: 90px">
<span class="level-tag" :class="item.levelClass">{{ <span class="level-tag" :class="item.levelClass">{{ item.pointLevel }}</span>
item.pointLevel
}}</span>
</div> </div>
<div class="td" style="width: 60px">{{ item.checkCount }}</div> <div class="td" style="width: 60px">{{ item.checkCount }}</div>
<div class="td" style="width: 120px"> <div class="td" style="width: 120px">
@ -134,9 +93,7 @@
</div> </div>
</div> </div>
<div class="td" style="width: 70px"> <div class="td" style="width: 70px">
<span class="response-status" :class="item.responseClass">{{ <span class="response-status" :class="item.responseClass">{{ item.responseStatus }}</span>
item.responseStatus
}}</span>
</div> </div>
<div class="td" style="width: 110px"> <div class="td" style="width: 110px">
<div class="time-info"> <div class="time-info">
@ -155,11 +112,7 @@
<div class="pagination"> <div class="pagination">
<span class="total">{{ total }}条数据</span> <span class="total">{{ total }}条数据</span>
<div class="page-btns"> <div class="page-btns">
<div <div class="page-btn" :class="{ disabled: currentPage === 1 }" @click="prevPage">
class="page-btn"
:class="{ disabled: currentPage === 1 }"
@click="prevPage"
>
<el-icon><ArrowLeft /></el-icon> <el-icon><ArrowLeft /></el-icon>
</div> </div>
<div <div
@ -171,11 +124,7 @@
> >
{{ page }} {{ page }}
</div> </div>
<div <div class="page-btn" :class="{ disabled: currentPage === totalPages }" @click="nextPage">
class="page-btn"
:class="{ disabled: currentPage === totalPages }"
@click="nextPage"
>
<el-icon><ArrowRight /></el-icon> <el-icon><ArrowRight /></el-icon>
</div> </div>
</div> </div>
@ -187,7 +136,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue"; import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import { pointTypeOptions, pointLevelOptions, isRespondedOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -205,22 +153,6 @@ const filterForm = ref({
isResponded: "", isResponded: "",
}); });
//
const tableColumns = ref([
{ label: "序号", width: "50px" },
{ label: "影响点类型", width: "80px" },
{ label: "影响点位置", width: "150px" },
{ label: "影响点等级", width: "90px" },
{ label: "查次数", width: "60px" },
{ label: "交通主管部门负责人", width: "120px" },
{ label: "公路机构责任人", width: "110px" },
{ label: "养护站负责人", width: "110px" },
{ label: "护路员", width: "80px" },
{ label: "回应状态", width: "70px" },
{ label: "最新催告时间", width: "110px" },
{ label: "操作", width: "50px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -328,7 +260,7 @@ watch(
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
} }
}, }
); );
</script> </script>
@ -347,13 +279,8 @@ watch(
} }
.response-status-dialog { .response-status-dialog {
width: 80vw; width: 1150px;
max-width: 1150px; background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
background: linear-gradient(
135deg,
rgba(20, 50, 90, 0.95) 0%,
rgba(10, 30, 60, 0.98) 100%
);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
padding: 24px; padding: 24px;
@ -373,13 +300,7 @@ watch(
font-weight: 600; font-weight: 600;
color: #fff; color: #fff;
padding: 8px 40px; padding: 8px 40px;
background: linear-gradient( background: linear-gradient(90deg, transparent 0%, rgba(64, 169, 255, 0.2) 20%, rgba(64, 169, 255, 0.2) 80%, transparent 100%);
90deg,
transparent 0%,
rgba(64, 169, 255, 0.2) 20%,
rgba(64, 169, 255, 0.2) 80%,
transparent 100%
);
border-bottom: 2px solid #40a9ff; border-bottom: 2px solid #40a9ff;
} }
@ -410,7 +331,6 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap;
gap: 12px; gap: 12px;
} }
@ -453,7 +373,7 @@ watch(
.table-header { .table-header {
display: flex; display: flex;
background-color: rgba(64, 169, 255, 0.2); background-color: rgba(64, 169, 255, 0.2);
padding: 12px 0; padding: 12px 16px;
.th { .th {
font-size: 13px; font-size: 13px;
@ -469,7 +389,7 @@ watch(
.table-row { .table-row {
display: flex; display: flex;
padding: 12px 0px; padding: 12px 16px;
align-items: center; align-items: center;
transition: background-color 0.3s; transition: background-color 0.3s;
@ -650,46 +570,4 @@ watch(
} }
} }
} }
//
.stats-cards {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-bottom: 20px;
.stat-card {
background: linear-gradient(
135deg,
rgba(30, 70, 120, 0.6) 0%,
rgba(20, 50, 90, 0.8) 100%
);
border: 2px solid rgba(64, 169, 255, 0.4);
border-radius: 8px;
padding: 16px 20px;
text-align: center;
transition: all 0.3s;
cursor: pointer;
&:hover {
border-color: rgba(64, 169, 255, 0.8);
box-shadow: 0 0 20px rgba(64, 169, 255, 0.3);
transform: translateY(-2px);
}
.stat-label {
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 8px;
font-weight: 500;
}
.stat-value {
font-size: 28px;
font-weight: bold;
color: #40a9ff;
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
}
}
}
</style> </style>

View File

@ -93,14 +93,9 @@
</div> </div>
<div class="responsible-table"> <div class="responsible-table">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 30%">责任人类型</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 40%">责任人</div>
:key="index" <div class="th" style="width: 30%">巡查频率</div>
class="th"
:style="{ width: column.width }"
>
{{ column.label }}
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -197,13 +192,6 @@ const props = defineProps({
const emit = defineEmits(["update:visible", "close", "viewTrack"]); const emit = defineEmits(["update:visible", "close", "viewTrack"]);
//
const tableColumns = ref([
{ label: "责任人类型", width: "30%" },
{ label: "责任人", width: "40%" },
{ label: "巡查频率", width: "30%" },
]);
// //
const basicInfo = ref({ const basicInfo = ref({
district: "合川区", district: "合川区",
@ -350,8 +338,7 @@ watch(
} }
.risk-dialog { .risk-dialog {
width: 80vw; width: 800px;
max-width: 800px;
max-height: 90vh; max-height: 90vh;
overflow-y: auto; overflow-y: auto;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);

View File

@ -24,7 +24,7 @@ defineProps({
<style lang="scss" scoped> <style lang="scss" scoped>
.section-header { .section-header {
height: 6.6667vw; height: 50px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -35,51 +35,20 @@ defineProps({
.header-left { .header-left {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1.0667vw; gap: 8px;
font-size: 1.3333vw;
.title { .title {
margin-left: 2.667vw; margin-left: 35px;
font-size: 14px;
font-weight: bold; font-weight: bold;
color: #fff; color: #fff;
font-size: 1vw;
} }
} }
.header-right { .header-right {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1.0667vw; gap: 8px;
}
@media (max-width: 768px) {
height: 10.6667vw;
.header-left {
gap: 2.1333vw;
.title {
margin-left: 8vw;
font-size: 1vw;
font-weight: bold;
color: #fff;
}
}
.header-right {
gap: 2.1333vw;
}
}
}
//
::v-deep(.header-left .title),
::v-deep(.header-left > span),
::v-deep(.header-left > div) {
font-weight: bold;
color: #fff;
@media (max-width: 768px) {
font-size: 4vw;
} }
} }
</style> </style>

View File

@ -12,14 +12,13 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 140px">区县/镇街</div>
:key="index" <div class="th" style="width: 100px">姓名</div>
class="th" <div class="th" style="width: 120px">电话</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 180px">驻地名称</div>
> <div class="th" style="flex: 1">类型</div>
{{ column.label }} <div class="th" style="width: 140px">调度</div>
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -93,17 +92,6 @@ const props = defineProps({
const emit = defineEmits(["update:visible", "close", "video", "voice", "call", "stationNameClick"]); const emit = defineEmits(["update:visible", "close", "video", "voice", "call", "stationNameClick"]);
//
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "区县/镇街", width: "140px" },
{ label: "姓名", width: "100px" },
{ label: "电话", width: "120px" },
{ label: "驻地名称", width: "180px" },
{ label: "类型", flex: "1" },
{ label: "调度", width: "140px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -245,8 +233,7 @@ watch(
} }
.tongnan-dialog { .tongnan-dialog {
width: 80vw; width: 1000px;
max-width: 1000px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;

View File

@ -12,14 +12,16 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">区县/镇街</div>
:key="index" <div class="th" style="width: 70px">总人数</div>
class="th" <div class="th" style="width: 70px">吹哨人</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 130px">建设单位包保责任人</div>
> <div class="th" style="width: 130px">施工单位包保责任人</div>
{{ column.label }} <div class="th" style="width: 120px">驻地包保责任人</div>
</div> <div class="th" style="width: 120px">区县级包保责任人</div>
<div class="th" style="width: 120px">市级包保责任人</div>
<div class="th" style="width: 60px">操作</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -82,20 +84,6 @@ const props = defineProps({
const emit = defineEmits(["update:visible", "close", "detail"]); const emit = defineEmits(["update:visible", "close", "detail"]);
//
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "区县/镇街", width: "100px" },
{ label: "总人数", width: "70px" },
{ label: "吹哨人", width: "70px" },
{ label: "建设单位包保责任人", width: "130px" },
{ label: "施工单位包保责任人", width: "130px" },
{ label: "驻地包保责任人", width: "120px" },
{ label: "区县级包保责任人", width: "120px" },
{ label: "市级包保责任人", width: "120px" },
{ label: "操作", width: "60px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -214,8 +202,7 @@ watch(
} }
.responsible-dialog { .responsible-dialog {
width: 80vw; width: 1100px;
max-width: 1100px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -281,7 +268,7 @@ watch(
} }
.table-body { .table-body {
max-height: 40vh; max-height: 320px;
overflow-y: auto; overflow-y: auto;
.table-row { .table-row {

View File

@ -12,14 +12,14 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">区县</div>
:key="index" <div class="th" style="width: 80px">总人数</div>
class="th" <div class="th" style="width: 140px">交通主管部门责任人</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 120px">公路机构责任人</div>
> <div class="th" style="width: 140px">养护站道班责任人</div>
{{ column.label }} <div class="th" style="width: 80px">护路员</div>
</div> <div class="th" style="flex: 1">操作</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -79,18 +79,6 @@ const props = defineProps({
const emit = defineEmits(["update:visible", "close", "view"]); const emit = defineEmits(["update:visible", "close", "view"]);
//
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "区县", width: "100px" },
{ label: "总人数", width: "80px" },
{ label: "交通主管部门责任人", width: "140px" },
{ label: "公路机构责任人", width: "120px" },
{ label: "养护站道班责任人", width: "140px" },
{ label: "护路员", width: "80px" },
{ label: "操作", flex: "1" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -223,8 +211,7 @@ watch(
} }
.team-dialog { .team-dialog {
width: 80vw; width: 900px;
max-width: 900px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -290,7 +277,7 @@ watch(
} }
.table-body { .table-body {
max-height: 40vh; max-height: 320px;
overflow-y: auto; overflow-y: auto;
.table-row { .table-row {

View File

@ -8,35 +8,22 @@
<div class="dialog-header"> <div class="dialog-header">
<div class="header-title"> <div class="header-title">
<span class="title-text">{{ rescueTeamData.title }}</span> <span class="title-text">{{ data.title }}</span>
<img <img class="title-icon" src="../../../assets/RiskWarning_img/图标_media_dvr@2x.png" alt="" />
class="title-icon"
src="../../../assets/RiskWarning_img/图标_media_dvr@2x.png"
alt=""
/>
</div> </div>
<!-- <div class="close-btn" @click="closeDialog"> <!-- <div class="close-btn" @click="closeDialog">
<span class="close-icon">×</span> <span class="close-icon">×</span>
</div> --> </div> -->
<div class="close-btn" style="pointer-events: auto" @click="closeDialog"> <div class="close-btn" style="pointer-events: auto;" @click="closeDialog">
<el-icon color="#5DD7F6"><Close /></el-icon> <el-icon color="#5DD7F6"><Close /></el-icon>
</div> </div>
</div> </div>
<div class="dialog-content"> <div class="dialog-content">
<div class="info-item" v-for="(item, index) in rescueTeamData.items" :key="index"> <div class="info-item" v-for="(item, index) in data.items" :key="index">
<label class="info-label">{{ item.label }}</label> <label class="info-label">{{ item.label }}</label>
<span class="info-value">{{ item.value }}</span> <span class="info-value">{{ item.value }}</span>
</div> </div>
</div> </div>
<div class="dialog-imgs">
<img
class="dialog-img"
v-for="(img, index) in rescueTeamData.imgs"
:key="index"
:src="img"
alt=""
/>
</div>
</div> </div>
</template> </template>
@ -69,6 +56,7 @@ defineProps({
], ],
}), }),
}, },
}); });
// //
@ -135,7 +123,6 @@ const rescueTeamData = {
{ label: "地址", value: "重庆市江津区双福工业园区赵坪路 157 号" }, { label: "地址", value: "重庆市江津区双福工业园区赵坪路 157 号" },
{ label: "物资装备", value: "应急物资:8100 件;应急装备:33 台" }, { label: "物资装备", value: "应急物资:8100 件;应急装备:33 台" },
], ],
imgs: ["", "", "", "", ""],
}; };
defineExpose({ defineExpose({
@ -158,30 +145,22 @@ const closeDialog = () => {
@return calc($px / 1920 * 100vw); @return calc($px / 1920 * 100vw);
} }
.tunnel-info-dialog { .tunnel-info-dialog {
max-width: vw(300);
width: vw(300); width: vw(300);
max-height: vw(600); width: 250px;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
background: rgba(64, 169, 255, 0.2); background: rgba(64, 169, 255, 0.2);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
position: fixed; position: fixed;
top: 20%; top: 20%;
left: 45%; left: 45%;
z-index: 1000;
&::-webkit-scrollbar {
display: none;
}
// //
.corner { .corner {
position: absolute; position: absolute;
width: vw(20); width: vw(20);
height: vw(20); height: vw(20);
border: 1px solid #40a9ff; border: 2px solid #40a9ff;
pointer-events: none; pointer-events: none;
&.corner-top-left { &.corner-top-left {
@ -189,6 +168,7 @@ const closeDialog = () => {
left: 0; left: 0;
border-right: none; border-right: none;
border-bottom: none; border-bottom: none;
border-top-left-radius: 6px;
} }
&.corner-top-right { &.corner-top-right {
@ -196,6 +176,7 @@ const closeDialog = () => {
right: 0; right: 0;
border-left: none; border-left: none;
border-bottom: none; border-bottom: none;
border-top-right-radius: 6px;
} }
&.corner-bottom-left { &.corner-bottom-left {
@ -203,6 +184,7 @@ const closeDialog = () => {
left: 0; left: 0;
border-right: none; border-right: none;
border-top: none; border-top: none;
border-bottom-left-radius: 6px;
} }
&.corner-bottom-right { &.corner-bottom-right {
@ -210,6 +192,7 @@ const closeDialog = () => {
right: 0; right: 0;
border-left: none; border-left: none;
border-top: none; border-top: none;
border-bottom-right-radius: 6px;
} }
} }
@ -281,14 +264,4 @@ const closeDialog = () => {
} }
} }
} }
.dialog-imgs {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: vw(6);
padding: vw(16) vw(20);
.dialog-img {
width: vw(75);
height: vw(75);
}
}
</style> </style>

View File

@ -14,42 +14,35 @@
<div class="filter-row"> <div class="filter-row">
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.warningLevel" placeholder="预警等级" class="filter-select"> <el-select v-model="filterForm.warningLevel" placeholder="预警等级" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in warningLevelOptions" <el-option label="红色预警" value="red" />
:key="option.value" <el-option label="橙色预警" value="orange" />
:label="option.label" <el-option label="黄色预警" value="yellow" />
:value="option.value" <el-option label="蓝色预警" value="blue" />
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select"> <el-select v-model="filterForm.region" placeholder="行政区域" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in regionOptionsWithAll" <el-option label="万州区" value="wanzhou" />
:key="option.value" <el-option label="涪陵区" value="fuling" />
:label="option.label" <el-option label="万盛区" value="wansheng" />
:value="option.value" <el-option label="长寿区" value="changshou" />
/> <el-option label="城口区" value="chengkou" />
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.isEnded" placeholder="是否结束" class="filter-select"> <el-select v-model="filterForm.isEnded" placeholder="是否结束" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in isEndedOptions" <el-option label="是" value="yes" />
:key="option.value" <el-option label="否" value="no" />
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-select v-model="filterForm.isResponded" placeholder="是否回应" class="filter-select"> <el-select v-model="filterForm.isResponded" placeholder="是否回应" class="filter-select">
<el-option <el-option label="全部" value="" />
v-for="option in isRespondedOptions" <el-option label="是" value="yes" />
:key="option.value" <el-option label="否" value="no" />
:label="option.label"
:value="option.value"
/>
</el-select> </el-select>
</div> </div>
<div class="filter-item"> <div class="filter-item">
@ -64,14 +57,16 @@
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 60px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">预警等级</div>
:key="index" <div class="th" style="width: 100px">行政区域</div>
class="th" <div class="th" style="width: 160px">预警时间</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 160px">结束时间</div>
> <div class="th" style="width: 100px">影响点数量</div>
{{ column.label }} <div class="th clickable" style="width: 80px">已叫应</div>
</div> <div class="th" style="width: 80px">已回应</div>
<div class="th" style="width: 80px">未回应</div>
<div class="th" style="width: 80px">已催告</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -124,7 +119,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close, Search, ArrowLeft, ArrowRight } from "@element-plus/icons-vue"; import { Close, Search, ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
import { warningLevelOptions, regionOptionsWithAll, isEndedOptions, isRespondedOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -143,20 +137,6 @@ const filterForm = ref({
isResponded: "", isResponded: "",
}); });
//
const tableColumns = ref([
{ label: "序号", width: "60px" },
{ label: "预警等级", width: "100px" },
{ label: "行政区域", width: "100px" },
{ label: "预警时间", width: "160px" },
{ label: "结束时间", width: "160px" },
{ label: "影响点数量", width: "100px" },
{ label: "已叫应", width: "80px" },
{ label: "已回应", width: "80px" },
{ label: "未回应", width: "80px" },
{ label: "已催告", width: "80px" },
]);
// //
const tableData = ref([ const tableData = ref([
{ {
@ -224,45 +204,6 @@ const tableData = ref([
notResponded: 0, notResponded: 0,
urged: 15, urged: 15,
}, },
{
id: 5,
warningLevel: "红色预警",
levelClass: "level-red",
region: "城口区",
warningTime: "2025-08-11 04:53:42",
endTime: "2025-08-11 04:53:42",
impactPoints: 0,
called: 0,
responded: 0,
notResponded: 0,
urged: 15,
},
{
id: 5,
warningLevel: "红色预警",
levelClass: "level-red",
region: "城口区",
warningTime: "2025-08-11 04:53:42",
endTime: "2025-08-11 04:53:42",
impactPoints: 0,
called: 0,
responded: 0,
notResponded: 0,
urged: 15,
},
{
id: 5,
warningLevel: "红色预警",
levelClass: "level-red",
region: "城口区",
warningTime: "2025-08-11 04:53:42",
endTime: "2025-08-11 04:53:42",
impactPoints: 0,
called: 0,
responded: 0,
notResponded: 0,
urged: 15,
},
]); ]);
// //
@ -364,8 +305,7 @@ watch(
} }
.warning-dialog { .warning-dialog {
width: 80vw; width: 1100px;
max-width: 1000px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -423,7 +363,7 @@ watch(
.filter-item { .filter-item {
.filter-select { .filter-select {
width: 120px; width: 140px;
:deep(.el-input__wrapper) { :deep(.el-input__wrapper) {
background-color: rgba(30, 70, 120, 0.4); background-color: rgba(30, 70, 120, 0.4);

View File

@ -45,35 +45,19 @@
/> />
</el-select> </el-select>
</div> </div>
<div class="filter-item">
<span class="filter-label">时间范围</span>
<el-date-picker
v-model="filterForm.dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="date-range-picker"
width="210px"
style="width: 210px"
clearable
value-format="YYYY-MM-DD"
/>
</div>
</div> </div>
</div> </div>
<!-- 数据表格 --> <!-- 数据表格 -->
<div class="table-section"> <div class="table-section">
<div class="table-header"> <div class="table-header">
<div <div class="th" style="width: 50px">序号</div>
v-for="(column, index) in tableColumns" <div class="th" style="width: 100px">预警等级</div>
:key="index" <div class="th" style="width: 100px">气象类型</div>
class="th" <div class="th" style="width: 100px">行政区域</div>
:style="{ width: column.width, flex: column.flex || 'none' }" <div class="th" style="width: 160px">预警时间</div>
> <div class="th" style="width: 160px">结束时间</div>
{{ column.label }} <div class="th" style="flex: 1">影响点数量</div>
</div>
</div> </div>
<div class="table-body"> <div class="table-body">
<div <div
@ -124,7 +108,6 @@
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue"; import { Close } from "@element-plus/icons-vue";
import { warningLevelOptions, regionOptions, isEndedOptions } from "./index.js";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -140,27 +123,28 @@ const filterForm = ref({
warningLevel: "", warningLevel: "",
region: "", region: "",
isEnded: "", isEnded: "",
dateRange: [],
}); });
// //
// index.js const warningLevelOptions = ref([
{ label: "红色预警", value: "红色预警" },
{ label: "橙色预警", value: "橙色预警" },
{ label: "黄色预警", value: "黄色预警" },
{ label: "蓝色预警", value: "蓝色预警" },
]);
// //
// index.js const regionOptions = ref([
{ label: "重庆市", value: "重庆市" },
{ label: "万州区", value: "万州区" },
{ label: "沙坪坝区", value: "沙坪坝区" },
{ label: "渝中区", value: "渝中区" },
]);
// //
// index.js const isEndedOptions = ref([
{ label: "是", value: "是" },
// { label: "否", value: "否" },
const tableColumns = ref([
{ label: "序号", width: "50px" },
{ label: "预警等级", width: "100px" },
{ label: "气象类型", width: "100px" },
{ label: "行政区域", width: "100px" },
{ label: "预警时间", width: "160px" },
{ label: "结束时间", width: "160px" },
{ label: "影响点数量", flex: "1" },
]); ]);
// //
@ -306,8 +290,7 @@ watch(
} }
.warning-dialog { .warning-dialog {
width: 80vw; width: 950px;
max-width: 900px;
background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%); background: linear-gradient(135deg, rgba(20, 50, 90, 0.95) 0%, rgba(10, 30, 60, 0.98) 100%);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 12px; border-radius: 12px;
@ -358,8 +341,7 @@ watch(
.filter-row { .filter-row {
display: flex; display: flex;
flex-wrap: wrap; gap: 24px;
gap: 12px;
} }
.filter-item { .filter-item {
@ -381,7 +363,6 @@ watch(
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: none; box-shadow: none;
border-radius: 4px; border-radius: 4px;
width: 210px !important;
.el-input__inner { .el-input__inner {
color: #fff; color: #fff;
@ -399,47 +380,6 @@ watch(
} }
} }
} }
.date-range-picker {
:deep(.el-input__wrapper) {
background-color: rgba(30, 70, 120, 0.4);
border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: none;
border-radius: 4px;
width: 210px !important;
.el-input__inner {
color: #fff;
font-size: 13px;
background: transparent;
&::placeholder {
color: rgba(255, 255, 255, 0.4);
}
}
.el-input__suffix {
.el-icon {
color: rgba(255, 255, 255, 0.6);
}
}
}
:deep(.el-range-input) {
background: transparent;
color: #fff;
font-size: 13px;
&::placeholder {
color: rgba(255, 255, 255, 0.4);
}
}
:deep(.el-range-separator) {
color: rgba(255, 255, 255, 0.6);
font-size: 13px;
}
}
} }
} }
@ -615,62 +555,3 @@ watch(
background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%); background: linear-gradient(180deg, #69c0ff 0%, #40a9ff 100%);
} }
</style> </style>
<style lang="scss">
//
.el-picker-panel {
background: rgba(20, 50, 90, 0.98) !important;
border: 1px solid rgba(64, 169, 255, 0.3) !important;
.el-picker-panel__content {
color: #fff;
.el-date-table th {
color: rgba(255, 255, 255, 0.6);
border-bottom-color: rgba(64, 169, 255, 0.3);
}
.el-date-table td {
color: rgba(255, 255, 255, 0.8);
&.selected .el-date-table-cell {
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
}
&.today span {
color: #40a9ff;
font-weight: bold;
}
&.in-range,
&.start-date,
&.end-date {
background: rgba(64, 169, 255, 0.2);
}
}
}
.el-picker-panel__footer {
border-top: 1px solid rgba(64, 169, 255, 0.3);
.el-button {
background: rgba(30, 70, 120, 0.4);
border-color: rgba(64, 169, 255, 0.3);
color: #fff;
&:hover {
background: rgba(64, 169, 255, 0.3);
}
}
.el-button--primary {
background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border: none;
&:hover {
background: linear-gradient(135deg, #69c0ff 0%, #40a9ff 100%);
}
}
}
}
</style>

View File

@ -7,11 +7,7 @@
alt="" alt=""
/> />
<div class="title_img_box"> <div class="title_img_box">
<img <img class="title_img1" src="../../assets/RiskWarning_img/位图@2x.png" alt="" />
class="title_img1"
src="../../assets/RiskWarning_img/位图@2x.png"
alt=""
/>
<img <img
class="title_img2" class="title_img2"
src="../../assets/RiskWarning_img/渝路畅行-风险预警一键响应@2x.png" src="../../assets/RiskWarning_img/渝路畅行-风险预警一键响应@2x.png"
@ -48,9 +44,7 @@
<div <div
class="center-info-card" class="center-info-card"
v-if=" v-if="showCenterCard.type === 'second' || showCenterCard.type === 'third'"
showCenterCard.type === 'second' || showCenterCard.type === 'third'
"
> >
<div <div
class="card-title" class="card-title"
@ -96,6 +90,7 @@
@openClearanceSituation="openDialog('clearanceSituation')" @openClearanceSituation="openDialog('clearanceSituation')"
@openControlSituation="openDialog('controlSituation')" @openControlSituation="openDialog('controlSituation')"
></right> ></right>
</div> </div>
<!-- 地图中心 --> <!-- 地图中心 -->
<div class="center"> <div class="center">
@ -250,8 +245,8 @@
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import useMapStore from "@/map/stores/mapStore"; import useMapStore from '@/map/stores/mapStore'
import { useMapBase } from "../cockpit/composables/useMapBase"; import { useMapBase } from '../cockpit/composables/useMapBase'
import left from "./left.vue"; import left from "./left.vue";
import right from "./right.vue"; import right from "./right.vue";
import bottom from "./bottom.vue"; import bottom from "./bottom.vue";
@ -301,7 +296,7 @@ const dialogVisible = ref({
dispatchDistrict: false, dispatchDistrict: false,
tongnanTeam: false, tongnanTeam: false,
warningSituation: false, warningSituation: false,
tunnelInfo: false, tunnelInfo: true,
}); });
// //
@ -312,7 +307,7 @@ const openDialog = (dialogName) => {
// //
const closeDialog = (dialogName) => { const closeDialog = (dialogName) => {
// //
console.log("关闭弹窗", dialogName); console.log('关闭弹窗', dialogName)
dialogVisible.value[dialogName] = false; dialogVisible.value[dialogName] = false;
}; };
@ -335,12 +330,12 @@ const showCenterCard = ref(false);
// ==================== ==================== // ==================== ====================
const mapStore = useMapStore(); const mapStore = useMapStore()
/** /**
* 加载地图的业务底图与聚焦中心点 * 加载地图的业务底图与聚焦中心点
*/ */
const mapBase = useMapBase(mapStore); const mapBase = useMapBase(mapStore)
// ==================== ==================== // ==================== ====================
@ -349,8 +344,8 @@ const mapBase = useMapBase(mapStore);
*/ */
onMounted(() => { onMounted(() => {
// //
mapBase.loadBaseData(); mapBase.loadBaseData()
}); })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -374,6 +369,7 @@ onMounted(() => {
left: 0; left: 0;
width: 100%; width: 100%;
height: vw(100); height: vw(100);
min-height: 70px;
z-index: 100; z-index: 100;
.title_bg { .title_bg {
@ -414,35 +410,32 @@ onMounted(() => {
.left { .left {
position: absolute; position: absolute;
left: 0; left: 0;
top: vw(90); top: vw(100);
width: 25%; width: 25%;
height: calc(100% - #{vw(90)}); height: calc(100% - #{vw(100)});
z-index: 2;
} }
.right { .right {
position: absolute; position: absolute;
right: 0; right: 0;
top: vw(90); top: vw(100);
width: 25%; width: 25%;
height: calc(100% - #{vw(90)}); height: calc(100% - #{vw(100)});
z-index: 2;
} }
.bottom { .bottom {
position: absolute; position: absolute;
bottom: 5px; bottom: 0px;
left: 25%; left: 30%;
width: 50%; width: 40%;
height: 43%; height: 50%;
} }
.top { .top {
position: absolute; position: absolute;
top: vw(100); top: vw(120);
left: 25%; left: 30%;
width: 50%; width: 40%;
z-index: 2;
// height: 15%; // height: 15%;
// background-color: #15293B; // background-color: #15293B;
} }
@ -453,7 +446,7 @@ onMounted(() => {
// left: 25%; // left: 25%;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: -1;
} }
/* 地图底层 - 填满整个容器 */ /* 地图底层 - 填满整个容器 */
@ -471,16 +464,17 @@ onMounted(() => {
z-index: 1; z-index: 1;
pointer-events: none; pointer-events: none;
/* 不阻挡交互 */ /* 不阻挡交互 */
background: url(../../assets/RiskWarning_img/遮罩层.png) no-repeat background: url(../../assets/RiskWarning_img/遮罩层.png) no-repeat center/cover;
center/cover;
} }
// //
.corner { .corner {
position: absolute; position: absolute;
width: vw(20); width: vw(30);
height: vw(20); height: vw(30);
border: 1px solid #40a9ff; min-width: 20px;
min-height: 20px;
border: 2px solid #40a9ff;
z-index: 100; z-index: 100;
pointer-events: none; pointer-events: none;
@ -489,6 +483,7 @@ onMounted(() => {
left: vw(10); left: vw(10);
border-right: none; border-right: none;
border-bottom: none; border-bottom: none;
border-top-left-radius: 4px;
} }
&.corner-top-right { &.corner-top-right {
@ -496,6 +491,7 @@ onMounted(() => {
right: vw(10); right: vw(10);
border-left: none; border-left: none;
border-bottom: none; border-bottom: none;
border-top-right-radius: 4px;
} }
&.corner-bottom-left { &.corner-bottom-left {
@ -503,6 +499,7 @@ onMounted(() => {
left: vw(10); left: vw(10);
border-right: none; border-right: none;
border-top: none; border-top: none;
border-bottom-left-radius: 4px;
} }
&.corner-bottom-right { &.corner-bottom-right {
@ -510,16 +507,17 @@ onMounted(() => {
right: vw(10); right: vw(10);
border-left: none; border-left: none;
border-top: none; border-top: none;
border-bottom-right-radius: 4px;
} }
} }
.center-info-card-container { .center-info-card-container {
position: absolute; position: absolute;
top: 30%; top: 30%;
left: 32%; left: 35%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: vw(200); width: vw(250);
min-width: 200px; min-width: 180px;
z-index: 200; z-index: 200;
} }
// //
@ -527,9 +525,7 @@ onMounted(() => {
background: rgba(64, 169, 255, 0.2); background: rgba(64, 169, 255, 0.2);
border: 1px solid rgba(64, 169, 255, 0.3); border: 1px solid rgba(64, 169, 255, 0.3);
z-index: 50; z-index: 50;
box-shadow: box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
0 4px 20px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
margin-bottom: vw(10); margin-bottom: vw(10);

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="left-panel"> <div class="left-panel">
<!-- 智能研判头部 --> <!-- 智能研判头部 -->
<SectionHeader title="智能研判"> <SectionHeader>
<template #left> <template #left>
<div class="filter-header"> <div class="filter-header">
<span class="title">智能研判</span> <span>智能研判</span>
<img <img
class="filter-icon-ai" class="filter-icon-ai"
src="../../assets/RiskWarning_img/AI1@2x.png" src="../../assets/RiskWarning_img/AI1@2x.png"
@ -32,8 +32,8 @@
alt="" alt=""
/> />
<div class="card-info"> <div class="card-info">
<div class="card-num mt_5">{{ item.value }}</div> <div class="card-num mt_10">{{ item.value }}</div>
<div class="card-label mb_5">{{ item.label }}</div> <div class="card-label mb_10">{{ item.label }}</div>
</div> </div>
</div> </div>
</div> </div>
@ -86,12 +86,7 @@
<div class="district-table-section"> <div class="district-table-section">
<el-table <el-table
:data="districtData" :data="districtData"
style=" style="width: 100%; background: transparent; font-size: 12px"
width: 100%;
background: transparent;
font-size: 12px;
height: 150px;
"
:header-cell-style="headerCellStyle" :header-cell-style="headerCellStyle"
:cell-style="cellStyle" :cell-style="cellStyle"
size="small" size="small"
@ -177,8 +172,7 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed } from "vue";
import request from "../../../../shared/api/request";
import SectionHeader from "./component/sectionHeader.vue"; import SectionHeader from "./component/sectionHeader.vue";
@ -242,49 +236,27 @@ import imgHelp from "../../assets/RiskWarning_img/响应图标5@2x.png";
import imgCheck from "../../assets/RiskWarning_img/抽查人数icon@2x.png"; import imgCheck from "../../assets/RiskWarning_img/抽查人数icon@2x.png";
// //
const weatherWarningData = ref([ const weatherWarningData = [
{ label: "红色预警", value: "8/13", class: "red" }, { label: "红色预警", value: '8/13', class: "red" },
{ label: "橙色预警", value: "12/14", class: "orange" }, { label: "橙色预警", value: '12/14', class: "orange" },
{ label: "黄色预警", value: "27/15", class: "yellow" }, { label: "黄色预警", value: '27/15', class: "yellow" },
{ label: "蓝色预警", value: "15/15", class: "blue" }, { label: "蓝色预警", value: '15/15', class: "blue" },
]); ];
// //
const impactData = ref([ const impactData = [
{ label: "路段", value: 830 }, { label: "路段", value: 830 },
{ label: "桥梁", value: 312 }, { label: "桥梁", value: 312 },
{ label: "隧道", value: 405 }, { label: "隧道", value: 405 },
{ label: "边坡", value: 634 }, { label: "边坡", value: 634 },
{ label: "项目", value: 523 }, { label: "项目", value: 523 },
]); ];
// //
const dateRange = ref([]); const dateRange = ref([]);
//
const loadData = async () => {
try {
const response = await request.get(
"/snow-ops-platform/weatherWarning/statistics",
);
if (response.data) {
const data = response.data;
if (data.weatherWarning) {
weatherWarningData.value = data.weatherWarning;
}
if (data.impactData) {
impactData.value = data.impactData;
}
}
} catch (error) {
console.error("加载数据失败:", error);
}
};
// //
const maxValue = computed(() => { const maxValue = Math.max(...impactData.map((item) => item.value));
return Math.max(...impactData.value.map((item) => item.value));
});
// //
const getBarHeight = (value) => { const getBarHeight = (value) => {
@ -381,27 +353,21 @@ const cellStyle = () => ({
textAlign: "center", textAlign: "center",
lineHeight: "1.2", lineHeight: "1.2",
}); });
onMounted(() => {
loadData();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.filter-header { .filter-header {
margin-left: 2.667vw; margin-left: 35px;
align-items: center;
color: #fff;
font-weight: bold;
display: flex; display: flex;
align-items: center; align-items: center;
.title { gap: vw(8);
font-size: 1vw; color: #fff;
} font-size: vw(24);
font-weight: bold;
} }
.filter-icon-ai { .filter-icon-ai {
width: 1.5em; width: 30px;
height: 1.5em; height: 30px;
margin-left: 10px; margin-left: 10px;
} }
// - // -
@ -434,6 +400,7 @@ onMounted(() => {
.section-header { .section-header {
height: vw(50); height: vw(50);
min-height: 40px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -448,6 +415,7 @@ onMounted(() => {
gap: vw(8); gap: vw(8);
margin-left: vw(35); margin-left: vw(35);
color: #fff; color: #fff;
font-size: vw(24);
font-weight: bold; font-weight: bold;
.icon-back { .icon-back {
@ -455,7 +423,7 @@ onMounted(() => {
height: vw(20); height: vw(20);
min-width: 16px; min-width: 16px;
min-height: 16px; min-height: 16px;
background: linear-gradient(135deg, #18f2f9 0%, #1890ff 100%); background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border-radius: 4px; border-radius: 4px;
display: flex; display: flex;
align-items: center; align-items: center;
@ -464,8 +432,15 @@ onMounted(() => {
&::before { &::before {
content: "←"; content: "←";
color: #fff; color: #fff;
font-size: vw(12);
} }
} }
.title {
font-size: vw(12);
font-weight: bold;
color: #fff;
}
} }
.header-date { .header-date {
@ -488,16 +463,18 @@ onMounted(() => {
.warning-cards { .warning-cards {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: vw(10);
display: flex; display: flex;
gap: vw(5);
.warning-card { .warning-card {
display: flex; display: flex;
align-items: center; align-items: center;
gap: vw(10);
flex: 1; flex: 1;
// padding: 12px; // padding: 12px;
background: rgba(64, 169, 255, 0.1); background: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.2); border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 6px;
.card-icon { .card-icon {
width: 100%; width: 100%;
@ -516,7 +493,7 @@ onMounted(() => {
.card-info { .card-info {
flex: 1; flex: 1;
.card-num { .card-num {
font-size: vw(18); font-size: vw(20);
font-weight: bold; font-weight: bold;
margin-bottom: 2px; margin-bottom: 2px;
} }
@ -537,7 +514,7 @@ onMounted(() => {
color: #ffc53d; color: #ffc53d;
} }
&.blue .card-num { &.blue .card-num {
color: #379afd; color: #40a9ff;
} }
} }
} }
@ -560,7 +537,7 @@ onMounted(() => {
.impact-detail { .impact-detail {
font-size: vw(14); font-size: vw(14);
color: #18f2f9; color: #40a9ff;
cursor: pointer; cursor: pointer;
&.clickable { &.clickable {
@ -576,7 +553,8 @@ onMounted(() => {
.chart-container { .chart-container {
position: relative; position: relative;
height: vw(100); height: vw(120);
height: 70px;
display: flex; display: flex;
// padding: 10px 0 30px 40px; // padding: 10px 0 30px 40px;
@ -630,7 +608,7 @@ onMounted(() => {
background: rgba(64, 169, 255, 0.15); background: rgba(64, 169, 255, 0.15);
.bar-value { .bar-value {
color: #18f2f9; color: #40a9ff;
transform: scale(1.1); transform: scale(1.1);
} }
@ -661,7 +639,7 @@ onMounted(() => {
min-width: 16px; min-width: 16px;
background: linear-gradient( background: linear-gradient(
180deg, 180deg,
#18f2f9 0%, #40a9ff 0%,
rgba(64, 169, 255, 0.3) 100% rgba(64, 169, 255, 0.3) 100%
); );
border-radius: 2px 2px 0 0; border-radius: 2px 2px 0 0;
@ -710,18 +688,19 @@ onMounted(() => {
align-items: center; align-items: center;
padding: vw(12) vw(16); padding: vw(12) vw(16);
background: rgba(64, 169, 255, 0.1); background: rgba(64, 169, 255, 0.1);
border: 1px solid #1d4c60; border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 6px;
box-shadow: inset 0px 0px 8px 0px rgba(55, 155, 255, 0.2); box-shadow: inset 0px 0px 8px 0px rgba(55, 155, 255, 0.2);
.card-label { .card-label {
font-size: vw(18); font-size: vw(14);
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
} }
.card-value { .card-value {
font-size: vw(22); font-size: vw(24);
font-weight: bold; font-weight: bold;
color: #18f2f9; color: #40a9ff;
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5); text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
} }
} }
@ -790,7 +769,6 @@ onMounted(() => {
margin-top: vw(20); margin-top: vw(20);
.section-header { .section-header {
height: vw(50);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -810,7 +788,7 @@ onMounted(() => {
height: vw(20); height: vw(20);
min-width: 16px; min-width: 16px;
min-height: 16px; min-height: 16px;
background: linear-gradient(135deg, #18f2f9 0%, #1890ff 100%); background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border-radius: 4px; border-radius: 4px;
display: flex; display: flex;
align-items: center; align-items: center;
@ -822,6 +800,12 @@ onMounted(() => {
font-size: vw(12); font-size: vw(12);
} }
} }
.title {
font-size: vw(14);
font-weight: bold;
color: #fff;
}
} }
.header-filters { .header-filters {
@ -831,11 +815,17 @@ onMounted(() => {
font-size: vw(10); font-size: vw(10);
.filter-item { .filter-item {
color: #fff; color: rgba(255, 255, 255, 0.6);
padding: vw(8) vw(8); padding: vw(3) vw(8);
background: #183c67; border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: inset 0px 0px 8px 0px #4fecff; border-radius: 4px;
cursor: pointer; cursor: pointer;
&.active {
background: rgba(64, 169, 255, 0.2);
color: #40a9ff;
border-color: rgba(64, 169, 255, 0.5);
}
} }
.filter-separator { .filter-separator {
@ -848,18 +838,16 @@ onMounted(() => {
.stats-grid { .stats-grid {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
// gap: vw(10); gap: vw(10);
background: rgba(64, 169, 255, 0.1); margin-bottom: vw(15);
border: 1px solid rgba(64, 169, 255, 0.2);
margin-bottom: vw(10);
.stat-item { .stat-item {
display: flex; display: flex;
align-items: center; align-items: center;
// gap: vw(8); gap: vw(8);
padding: vw(10); padding: vw(10);
// background: rgba(64, 169, 255, 0.08); background: rgba(64, 169, 255, 0.08);
border-radius: 6px;
.stat-icon { .stat-icon {
width: 100%; width: 100%;
@ -894,7 +882,7 @@ onMounted(() => {
.stat-num { .stat-num {
font-size: vw(24); font-size: vw(24);
font-weight: bold; font-weight: bold;
color: #18f2f9; color: #40a9ff;
margin-bottom: 2px; margin-bottom: 2px;
} }
@ -910,7 +898,7 @@ onMounted(() => {
&:hover { &:hover {
background: rgba(64, 169, 255, 0.2); background: rgba(64, 169, 255, 0.2);
// transform: translateY(-2px); transform: translateY(-2px);
.stat-num { .stat-num {
color: #69c0ff; color: #69c0ff;
@ -931,6 +919,7 @@ onMounted(() => {
padding: vw(12); padding: vw(12);
background: rgba(64, 169, 255, 0.1); background: rgba(64, 169, 255, 0.1);
border: 1px solid rgba(64, 169, 255, 0.2); border: 1px solid rgba(64, 169, 255, 0.2);
border-radius: 6px;
text-align: center; text-align: center;
&.clickable { &.clickable {
@ -951,7 +940,7 @@ onMounted(() => {
.card-num { .card-num {
font-size: vw(20); font-size: vw(20);
font-weight: bold; font-weight: bold;
color: #18f2f9; color: #40a9ff;
margin-bottom: vw(6); margin-bottom: vw(6);
.unit { .unit {
@ -973,12 +962,11 @@ onMounted(() => {
.date-range-wrapper { .date-range-wrapper {
:deep(.el-date-editor) { :deep(.el-date-editor) {
border-radius: 0px !important; width: vw(200);
height: 3.1em !important; min-width: 140px;
} background: transparent;
:deep(.el-date-editor) { border: 1px solid rgba(64, 169, 255, 0.3);
width: 200px; border-radius: 4px;
max-width: vw(200);
background: #183c67; background: #183c67;
box-shadow: inset 0px 0px 8px 0px #4fecff; box-shadow: inset 0px 0px 8px 0px #4fecff;

View File

@ -26,14 +26,9 @@
<!-- 管控路段数 --> <!-- 管控路段数 -->
<div class="control-section"> <div class="control-section">
<div class="control-title display jc_sb ai_center"> <div class="control-title">
<div class="f1">
管控路段数 <span class="control-num">2</span> 管控路段数 <span class="control-num">2</span>
</div> </div>
<div class="f1">
管控项目 <span class="control-num">2</span>
</div>
</div>
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
<div class="control-grid"> <div class="control-grid">
<div <div
@ -70,15 +65,9 @@
<!-- 巡查公路里程 --> <!-- 巡查公路里程 -->
<div class="patrol-section"> <div class="patrol-section">
<div class="patrol-header display jc_sb ai_center"> <div class="patrol-header">
<div>
<span class="patrol-title">巡查公路里程</span> <span class="patrol-title">巡查公路里程</span>
<span class="patrol-mileage ml_10">234882km</span> <span class="patrol-mileage">234882km</span>
</div>
<div>
<span class="patrol-title">巡查项目数</span>
<span class="patrol-mileage ml_10">6</span>
</div>
</div> </div>
<div class="patrol-grid"> <div class="patrol-grid">
<div <div
@ -223,8 +212,8 @@ import icon3 from "../../assets/RiskWarning_img/icon3@2x.png";
import icon4 from "../../assets/RiskWarning_img/icon4@2x.png"; import icon4 from "../../assets/RiskWarning_img/icon4@2x.png";
import icon11 from "../../assets/RiskWarning_img/icon-1@2x.png"; import icon11 from "../../assets/RiskWarning_img/icon-1@2x.png";
import icon12 from "../../assets/RiskWarning_img/icon-2@2x.png"; import icon12 from "../../assets/RiskWarning_img/icon-1@2x.png";
import icon13 from "../../assets/RiskWarning_img/icon-3@2x.png"; import icon13 from "../../assets/RiskWarning_img/icon-1@2x.png";
import icon51 from "../../assets/RiskWarning_img/编组5@2x.png"; import icon51 from "../../assets/RiskWarning_img/编组5@2x.png";
import icon52 from "../../assets/RiskWarning_img/编组22@2x.png"; import icon52 from "../../assets/RiskWarning_img/编组22@2x.png";
@ -288,7 +277,7 @@ const patrolData = [
{ label: "巡查桥梁数", value: "1" }, { label: "巡查桥梁数", value: "1" },
{ label: "巡查边坡数", value: "6" }, { label: "巡查边坡数", value: "6" },
{ label: "巡查隧道数", value: "10" }, { label: "巡查隧道数", value: "10" },
{ label: "发现隐患数", value: "6" }, { label: "巡查项目数", value: "6" },
]; ];
// //
@ -384,20 +373,19 @@ const majorEvent = "0";
justify-content: space-between; justify-content: space-between;
background-image: url("../../assets/RiskWarning_img/标题bg@2x.png"); background-image: url("../../assets/RiskWarning_img/标题bg@2x.png");
align-items: center; align-items: center;
margin-bottom: vw(8); margin-bottom: vw(15);
height: vw(50);
.header-left { .header-left {
display: flex; display: flex;
align-items: center; align-items: center;
gap: vw(6); gap: vw(8);
.icon-back { .icon-back {
width: vw(16); width: vw(20);
height: vw(16); height: vw(20);
min-width: 14px; min-width: 16px;
min-height: 14px; min-height: 16px;
background: linear-gradient(135deg, #18F2F9 0%, #1890ff 100%); background: linear-gradient(135deg, #40a9ff 0%, #1890ff 100%);
border-radius: 4px; border-radius: 4px;
display: flex; display: flex;
align-items: center; align-items: center;
@ -406,12 +394,12 @@ const majorEvent = "0";
&::before { &::before {
content: "←"; content: "←";
color: #fff; color: #fff;
font-size: vw(10); font-size: vw(12);
} }
} }
.title { .title {
font-size: vw(14); font-size: vw(12);
font-weight: bold; font-weight: bold;
color: #fff; color: #fff;
} }
@ -422,34 +410,34 @@ const majorEvent = "0";
.resource-grid { .resource-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
gap: vw(6); gap: vw(10);
margin-bottom: vw(6); margin-bottom: vw(10);
.resource-item { .resource-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: vw(6); gap: vw(10);
padding: vw(4) vw(8); padding: vw(8) vw(12);
background: linear-gradient(270deg, rgba(18, 52, 97, 0) 0%, #203555 100%); background: linear-gradient(270deg, rgba(18, 84, 97, 0) 0%, #204a55 100%);
border: 2px solid transparent; border: 2px solid transparent;
border-image: linear-gradient( border-image: linear-gradient(
270deg, 270deg,
rgba(80, 145, 201, 0), rgba(80, 201, 191, 0),
rgba(39, 77, 153, 1) rgba(39, 135, 153, 1)
) )
2 2; 2 2;
border-radius: 6px; border-radius: 6px;
border-right: 0px; border-right: 0px;
.resource-icon { .resource-icon {
width: vw(24); width: vw(32);
height: vw(24); height: vw(32);
min-width: 16px; min-width: 20px;
min-height: 16px; min-height: 20px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: vw(18); font-size: vw(20);
&.icon-team::before { &.icon-team::before {
content: "👷"; content: "👷";
@ -474,13 +462,13 @@ const majorEvent = "0";
width: 48%; width: 48%;
font-size: vw(12); font-size: vw(12);
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
margin-bottom: vw(2); margin-bottom: vw(4);
} }
.resource-value { .resource-value {
font-size: vw(16); font-size: vw(18);
font-weight: bold; font-weight: bold;
color: #18F2F9; color: #40a9ff;
.unit { .unit {
font-size: vw(12); font-size: vw(12);
@ -498,15 +486,14 @@ const majorEvent = "0";
margin-bottom: vw(10); margin-bottom: vw(10);
.control-title { .control-title {
font-size: vw(16); font-size: vw(14);
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
margin-bottom: vw(10); margin-bottom: vw(10);
font-weight: 600;
.control-num { .control-num {
font-size: vw(16); font-size: vw(16);
color: #18F2F9; color: #40a9ff;
font-weight: bold; font-weight: bold;
margin-left: vw(5); margin-left: vw(5);
} }
@ -516,13 +503,13 @@ const majorEvent = "0";
flex: 1; flex: 1;
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
background: rgba(62, 106, 172, 0.36); background: rgba(64, 169, 255, 0.1);
box-shadow: inset 0px 0px 8px 0px #379bff; box-shadow: inset 0px 0px 8px 0px #379bff;
gap: vw(8); gap: vw(8);
.control-item { .control-item {
text-align: center; text-align: center;
padding: vw(5) vw(5); padding: vw(6) vw(5);
// background: rgba(64, 169, 255, 0.1); // background: rgba(64, 169, 255, 0.1);
border-radius: 4px; border-radius: 4px;
@ -533,14 +520,18 @@ const majorEvent = "0";
&:hover { &:hover {
background-color: rgba(64, 169, 255, 0.15); background-color: rgba(64, 169, 255, 0.15);
.control-value {
color: #69c0ff;
text-shadow: 0 0 8px rgba(105, 192, 255, 0.6);
}
} }
} }
.control-value { .control-value {
font-size: vw(18); font-size: vw(18);
font-weight: bold; font-weight: bold;
color: #18F2F9; color: #40a9ff;
// margin-bottom: vw(4); margin-bottom: vw(4);
} }
.control-label { .control-label {
@ -562,14 +553,14 @@ const majorEvent = "0";
margin-bottom: vw(10); margin-bottom: vw(10);
.patrol-title { .patrol-title {
font-size: vw(16); font-size: vw(14);
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
} }
.patrol-mileage { .patrol-mileage {
font-size: vw(16); font-size: vw(16);
font-weight: bold; font-weight: bold;
color: #4FECFF; color: #40a9ff;
} }
} }
@ -590,7 +581,7 @@ const majorEvent = "0";
.patrol-value { .patrol-value {
font-size: vw(18); font-size: vw(18);
font-weight: bold; font-weight: bold;
color: #4FECFF; color: #40a9ff;
margin-bottom: vw(4); margin-bottom: vw(4);
text-align: left; text-align: left;
margin-left: vw(5); margin-left: vw(5);
@ -607,7 +598,7 @@ const majorEvent = "0";
// //
.rescue-section { .rescue-section {
.rescue-title { .rescue-title {
font-size: vw(16); font-size: vw(14);
color: rgba(255, 255, 255, 0.9); color: rgba(255, 255, 255, 0.9);
margin-bottom: vw(10); margin-bottom: vw(10);
} }
@ -630,8 +621,10 @@ const majorEvent = "0";
background-position: right; background-position: right;
.rescue-icon { .rescue-icon {
width: vw(40); width: vw(36);
height: vw(40); height: vw(36);
min-width: 24px;
min-height: 24px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -653,7 +646,7 @@ const majorEvent = "0";
.rescue-value { .rescue-value {
font-size: vw(18); font-size: vw(18);
font-weight: bold; font-weight: bold;
color: #fff; color: #40a9ff;
margin-bottom: vw(4); margin-bottom: vw(4);
display: flex; display: flex;
align-items: center; align-items: center;
@ -677,7 +670,7 @@ const majorEvent = "0";
// //
.disaster-section { .disaster-section {
margin-top: vw(10); margin-top: vw(15);
.block-section { .block-section {
margin-bottom: vw(10); margin-bottom: vw(10);
@ -696,7 +689,7 @@ const majorEvent = "0";
} }
.block-title { .block-title {
font-size: vw(16); font-size: vw(14);
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
margin-bottom: vw(10); margin-bottom: vw(10);
} }
@ -720,7 +713,7 @@ const majorEvent = "0";
background: linear-gradient( background: linear-gradient(
180deg, 180deg,
transparent 0%, transparent 0%,
#18F2F9 50%, #40a9ff 50%,
transparent 100% transparent 100%
); );
// margin: 0 auto; // margin: 0 auto;
@ -741,7 +734,7 @@ const majorEvent = "0";
margin-bottom: vw(6); margin-bottom: vw(6);
.current { .current {
color: #18F2F9; color: #40a9ff;
} }
.separator { .separator {
@ -763,7 +756,7 @@ const majorEvent = "0";
.death-num { .death-num {
font-size: vw(18); font-size: vw(18);
font-weight: bold; font-weight: bold;
color: #fff; color: #40a9ff;
margin-bottom: vw(6); margin-bottom: vw(6);
} }
@ -777,10 +770,10 @@ const majorEvent = "0";
} }
.damage-section { .damage-section {
margin-bottom: vw(5); margin-bottom: vw(10);
.damage-title { .damage-title {
font-size: vw(16); font-size: vw(14);
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
margin-bottom: vw(10); margin-bottom: vw(10);
} }
@ -788,7 +781,7 @@ const majorEvent = "0";
.damage-grid { .damage-grid {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
gap: vw(5); gap: vw(10);
.damage-item { .damage-item {
text-align: center; text-align: center;
@ -817,7 +810,7 @@ const majorEvent = "0";
} }
&.blue .damage-value { &.blue .damage-value {
color: #18F2F9; color: #40a9ff;
.unit { .unit {
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 0.7);
} }
@ -861,11 +854,17 @@ const majorEvent = "0";
font-size: vw(10); font-size: vw(10);
.filter-item { .filter-item {
color: #fff; color: rgba(255, 255, 255, 0.6);
padding: vw(8) vw(8); padding: vw(3) vw(8);
background: #183c67; border: 1px solid rgba(64, 169, 255, 0.3);
box-shadow: inset 0px 0px 8px 0px #4fecff; border-radius: 4px;
cursor: pointer; cursor: pointer;
&.active {
background: rgba(64, 169, 255, 0.2);
color: #40a9ff;
border-color: rgba(64, 169, 255, 0.5);
}
} }
.filter-separator { .filter-separator {
@ -874,12 +873,10 @@ const majorEvent = "0";
} }
.date-range-wrapper { .date-range-wrapper {
:deep(.el-date-editor) { :deep(.el-date-editor) {
border-radius: 0px !important; width: 200px;
height: 3.1em !important; background: transparent;
} border: 1px solid rgba(64, 169, 255, 0.3);
:deep(.el-date-editor) { border-radius: 4px;
width: vw(200);
max-width: vw(200);
background: #183c67; background: #183c67;
box-shadow: inset 0px 0px 8px 0px #4fecff; box-shadow: inset 0px 0px 8px 0px #4fecff;

View File

@ -64,11 +64,17 @@ const handleAIClick = () => {
font-size: vw(13); font-size: vw(13);
.filter-item { .filter-item {
color: #fff; color: rgba(255, 255, 255, 0.6);
padding: vw(8) vw(8); padding: 0 vw(12);
height: vw(24);
min-height: 20px;
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
background: #183c67; background: #183c67;
box-shadow: inset 0px 0px 8px 0px #4fecff; box-shadow: inset 0px 0px 8px 0px #4fecff;
cursor: pointer;
// &:hover { // &:hover {
// border-color: rgba(64, 169, 255, 0.5); // border-color: rgba(64, 169, 255, 0.5);
@ -83,13 +89,12 @@ const handleAIClick = () => {
} }
.date-range-wrapper { .date-range-wrapper {
:deep(.el-date-editor) {
border-radius: 0px !important;
height: 2.6em !important;
}
:deep(.el-date-editor) { :deep(.el-date-editor) {
width: vw(200); width: vw(200);
max-width: vw(200); min-width: 140px;
background: transparent;
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 4px;
background: #183c67; background: #183c67;
box-shadow: inset 0px 0px 8px 0px #4fecff; box-shadow: inset 0px 0px 8px 0px #4fecff;