地图添加涉灾隐患点,多种等级路段,国省道弹窗,农村道路,项目,弹窗title修改,涉灾隐患点详情。

This commit is contained in:
fanjia 2026-04-17 14:50:25 +08:00
parent 6cdc8e25cc
commit ccd22b7113
17 changed files with 2683 additions and 1545 deletions

10
.prettierrc Normal file
View File

@ -0,0 +1,10 @@
{
"printWidth": 100,
"tabWidth": 2,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "avoid",
"htmlWhitespaceSensitivity": "ignore",
"vueIndentScriptAndStyle": false
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -86,9 +86,9 @@
<!-- 管控措施列插槽 --> <!-- 管控措施列插槽 -->
<template #roadConditionType="{ row }"> <template #roadConditionType="{ row }">
<span :class="['control-tag', getControlClass(row.roadConditionType)]">{{ <span :class="['control-tag', getControlClass(row.roadConditionType)]">
row.roadConditionType {{ row.roadConditionType }}
}}</span> </span>
</template> </template>
<!-- 操作列插槽 --> <!-- 操作列插槽 -->
@ -99,15 +99,11 @@
</template> </template>
<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 { import { regionOptions, typeOptions, controlMeasureOptions } from '../component/index.js';
regionOptions, import BaseDialog from '../component/baseDialog.vue';
typeOptions, import { request } from '@/utils/request';
controlMeasureOptions,
} from "../component/index.js";
import BaseDialog from "../component/baseDialog.vue";
import { request } from "@/utils/request";
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -116,13 +112,13 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(["update:visible", "close", "detail"]); const emit = defineEmits(['update:visible', 'close', 'detail']);
// //
const filterForm = ref({ const filterForm = ref({
district: "", district: '',
type: "", type: '',
roadConditionType: "", roadConditionType: '',
}); });
// //
@ -139,21 +135,21 @@ const tableHeight = ref(300);
// //
const tableColumns = ref([ const tableColumns = ref([
{ prop: "id", label: "序号", width: "" }, { prop: 'id', label: '序号', width: '' },
{ prop: "district", label: "影响区域", width: "" }, { prop: 'district', label: '影响区域', width: '' },
{ prop: "routeNo", label: "线路编号", width: "" }, { prop: 'routeNo', label: '线路编号', width: '' },
{ prop: "stakeNo", label: "起止桩号", width: "", slot: "stakeNo" }, { prop: 'stakeNo', label: '起止桩号', width: '', slot: 'stakeNo' },
{ prop: "location", label: "路况位置", width: "", slot: "location" }, { prop: 'location', label: '路况位置', width: '', slot: 'location' },
{ prop: "occurrenceTime", label: "发生时间", width: "" }, { prop: 'occurrenceTime', label: '发生时间', width: '' },
// { prop: "routeNo2", label: "线", width: "" }, // { prop: "routeNo2", label: "线", width: "" },
{ prop: "type", label: "类型", width: "" }, { prop: 'type', label: '类型', width: '' },
{ {
prop: "roadConditionType", prop: 'roadConditionType',
label: "管控措施", label: '管控措施',
width: "", width: '',
slot: "roadConditionType", slot: 'roadConditionType',
}, },
{ prop: "operation", label: "操作", width: "", slot: "operation" }, { prop: 'operation', label: '操作', width: '', slot: 'operation' },
]); ]);
// //
@ -183,34 +179,34 @@ const visiblePages = computed(() => {
}); });
// //
const getControlClass = (measure) => { const getControlClass = measure => {
const classMap = { const classMap = {
全幅封闭: "control-close", 全幅封闭: 'control-close',
半幅封闭: "control-half", 半幅封闭: 'control-half',
正常通行: "control-normal", 正常通行: 'control-normal',
限制通行: "control-limit", 限制通行: 'control-limit',
}; };
return classMap[measure] || ""; return classMap[measure] || '';
}; };
// //
const handleClose = () => { const handleClose = () => {
emit("update:visible", false); emit('update:visible', false);
emit("close"); emit('close');
}; };
// //
const handleDetail = (item) => { const handleDetail = item => {
emit("detail", item); emit('detail', item);
}; };
// //
const handleSizeChange = (val) => { const handleSizeChange = val => {
pageSize.value = val; pageSize.value = val;
fetchData(); fetchData();
}; };
const handleCurrentChange = (val) => { const handleCurrentChange = val => {
currentPage.value = val; currentPage.value = val;
fetchData(); fetchData();
}; };
@ -224,19 +220,19 @@ const fetchData = async () => {
try { try {
// //
let measureType = 0; let measureType = 0;
if (filterForm.value.roadConditionType === "全幅封闭") { if (filterForm.value.roadConditionType === '全幅封闭') {
measureType = 1; measureType = 1;
} else if (filterForm.value.roadConditionType === "半幅封闭") { } else if (filterForm.value.roadConditionType === '半幅封闭') {
measureType = 2; measureType = 2;
} else if (filterForm.value.roadConditionType === "限速") { } else if (filterForm.value.roadConditionType === '限速') {
measureType = 3; measureType = 3;
} else if (filterForm.value.roadConditionType === "告警阻拦") { } else if (filterForm.value.roadConditionType === '告警阻拦') {
measureType = 4; measureType = 4;
} }
const res = await request({ const res = await request({
url: "/snow-ops-platform/sm-event/dashboard/control-list", url: '/snow-ops-platform/sm-event/dashboard/control-list',
method: "GET", method: 'GET',
params: { params: {
pageNum: currentPage.value, pageNum: currentPage.value,
pageSize: pageSize.value, pageSize: pageSize.value,
@ -244,40 +240,40 @@ const fetchData = async () => {
}, },
}); });
if (res.code === "00000" && res.data) { if (res.code === '00000' && res.data) {
const data = res.data; const data = res.data;
// //
tableData.value = data.records.map((item) => { tableData.value = data.records.map((item, index) => {
return { return {
id: item.id, id: currentPage.value * pageSize.value - (pageSize.value - index - 1),
district: item.district || "-", district: item.affectedArea || '-',
routeNo: item.routeNo || "-", routeNo: item.routeNo || '-',
stakeNo: `${item.startStakeNo}-${item.endStakeNo}` || "-", stakeNo: `${item.startStakeNo}-${item.endStakeNo}` || '-',
location: item.occurLocation || "-", location: item.occurLocation || '-',
occurrenceTime: item.occurTime || "-", occurrenceTime: item.occurTime || '-',
// routeNo2: item.routeNo || "-", // routeNo2: item.routeNo || "-",
type: item.roadConditionType || "-", type: item.roadConditionType || '-',
roadConditionType: item.roadConditionType || "-", roadConditionType: item.processingMeasure || '-',
expectRecoverTime: item.expectRecoverTime || "-", expectRecoverTime: item.expectRecoverTime || '-',
eventStatus: item.eventStatus || "-", eventStatus: item.eventStatus || '-',
}; };
}); });
total.value = data.total; total.value = data.total;
} }
} catch (error) { } catch (error) {
console.error("获取抢通情况数据失败:", error); console.error('获取抢通情况数据失败:', error);
} }
}; };
// visible // visible
watch( watch(
() => props.visible, () => props.visible,
(newVal) => { newVal => {
if (newVal) { if (newVal) {
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
} }
}, }
); );
</script> </script>

View File

@ -0,0 +1,369 @@
<template>
<base-dialog
v-model:visible="props.visible"
title="涉灾隐患点情况"
:table-data="tableData"
:table-columns="tableColumns"
:table-height="450"
:total="total"
:current-page="currentPage"
:page-size="pageSize"
:z-index="2000"
:max-width="900"
:show-filter="false"
:table-show="false"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@close="handleClose"
>
<!-- 自定义内容区域 -->
<template #header>
<div class="hazard-info-panel">
<!-- 基本信息 -->
<div class="info-section">
<div class="info-row">
<div class="info-item">
<span class="info-label">区县名称</span>
<span class="info-value">{{ hazardData.district }}</span>
</div>
<div class="info-item">
<span class="info-label">风险等级</span>
<span class="info-value">{{ hazardData.riskLevel }}</span>
</div>
</div>
<div class="info-row">
<div class="info-item">
<span class="info-label">公路编号</span>
<span class="info-value">{{ hazardData.roadCode }}</span>
</div>
<div class="info-item">
<span class="info-label">位置</span>
<span class="info-value">{{ hazardData.location }}</span>
</div>
</div>
</div>
<!-- 风险描述 -->
<div class="info-block">
<div class="block-title">风险描述</div>
<div class="block-content">{{ hazardData.riskDescription }}</div>
</div>
<!-- 采取措施 -->
<div class="info-block">
<div class="block-title">采取措施</div>
<div class="block-content">{{ hazardData.measures }}</div>
</div>
<!-- 三级包保责任人 -->
<div class="info-block">
<div class="block-title">三级包保责任人</div>
<div class="responsibility-list">
<div class="responsibility-item">
<span class="responsibility-label">交通主管部门责任人</span>
<span class="responsibility-name">{{ hazardData.trafficDept.name }}</span>
<span class="responsibility-phone">{{ hazardData.trafficDept.phone }}</span>
<span class="responsibility-frequency">{{ hazardData.trafficDept.frequency }}</span>
</div>
<div class="responsibility-item">
<span class="responsibility-label">公路机构责任人</span>
<span class="responsibility-name">{{ hazardData.roadOrg.name }}</span>
<span class="responsibility-phone">{{ hazardData.roadOrg.phone }}</span>
<span class="responsibility-frequency">{{ hazardData.roadOrg.frequency }}</span>
</div>
<div class="responsibility-item">
<span class="responsibility-label">养护站责任人</span>
<span class="responsibility-name">{{ hazardData.maintenance.name }}</span>
<span class="responsibility-phone">{{ hazardData.maintenance.phone }}</span>
<span class="responsibility-frequency">{{ hazardData.maintenance.frequency }}</span>
</div>
</div>
</div>
<!-- 护路员 -->
<div class="info-row simple-row">
<span class="row-label">护路员</span>
<span class="row-value name">{{ hazardData.roadKeeper.name }}</span>
<span class="row-value phone">{{ hazardData.roadKeeper.phone }}</span>
<span class="row-value frequency">{{ hazardData.roadKeeper.frequency }}</span>
</div>
<!-- 预警预报关 -->
<div class="info-row simple-row">
<span class="row-label">预警预报关</span>
<span class="row-value">{{ hazardData.earlyWarning }}</span>
</div>
<!-- 线下巡查关 -->
<div class="info-row simple-row">
<span class="row-label">线下巡查关</span>
<span class="row-value">{{ hazardData.offlinePatrol }}</span>
</div>
<!-- 交通管控关 -->
<div class="info-row simple-row">
<span class="row-label">交通管控关</span>
<span class="row-value">{{ hazardData.trafficControl }}</span>
</div>
<!-- 力量预置关 -->
<div class="info-row simple-row">
<span class="row-label">力量预置关</span>
<span class="row-value">{{ hazardData.forcePreposition }}</span>
<el-icon class="location-icon"><Location /></el-icon>
</div>
<!-- 告警阻拦关 -->
<div class="info-row simple-row">
<span class="row-label">告警阻拦关</span>
<span class="row-value">{{ hazardData.alarmBlocking }}</span>
</div>
</div>
</template>
</base-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
import { Location } from '@element-plus/icons-vue';
import baseDialog from '../component/baseDialog.vue';
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
data: {
type: Object,
default: () => ({}),
},
});
const emit = defineEmits(['update:visible', 'close']);
// 使
const tableColumns = ref([]);
const tableData = ref([]);
const total = ref(0);
const currentPage = ref(1);
const pageSize = ref(10);
//
const hazardData = ref({
district: '南川区',
riskLevel: '较大隐患',
roadCode: 'S523',
location: '开县-凭祥(K292+301至K292+386)',
riskDescription:
'崩塌形成于路线右侧上边坡陡峭位置影响长度85m掉块、滑塌可能性极大。【类型路内风险点-边坡】',
measures: '已纳入灾害防治工程计划,拟采用坡面整理及挂网喷射植被混凝土整治。',
trafficDept: {
name: '何思毅',
phone: '13896702005',
frequency: '半年巡查一次',
},
roadOrg: {
name: '杨洪',
phone: '15025697135',
frequency: '每月巡查一次',
},
maintenance: {
name: '陈李彪',
phone: '13896713399',
frequency: '每周巡查一次',
},
roadKeeper: {
name: '陈李彪',
phone: '13896713399',
frequency: '一周巡查两次',
},
earlyWarning: '当前无预警',
offlinePatrol: '常态化巡查',
trafficControl: '观察通行 半幅通行 禁止通行 无',
forcePreposition: '安宁养护站',
alarmBlocking: '设置警示标识 向社会发布信息 采取硬隔离措施 无',
});
//
const handleClose = () => {
emit('update:visible', false);
emit('close');
};
//
const handleSizeChange = val => {
pageSize.value = val;
};
const handleCurrentChange = val => {
currentPage.value = val;
};
// visible
watch(
() => props.visible,
newVal => {
if (newVal && props.data) {
//
Object.assign(hazardData.value, props.data);
}
}
);
</script>
<style lang="scss" scoped>
.hazard-info-panel {
height: 500px;
color: rgba(255, 255, 255, 0.9);
overflow-y: auto;
//
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: rgba(20, 46, 73, 0.3);
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #142e49;
border-radius: 3px;
&:hover {
background: #1a3a5c;
}
}
// Firefox
scrollbar-width: thin;
scrollbar-color: #142e49 rgba(20, 46, 73, 0.3);
.info-section {
margin-bottom: 16px;
}
.info-row {
display: flex;
margin-bottom: 12px;
&.simple-row {
align-items: center;
padding: 8px 0;
border-bottom: 1px solid rgba(64, 169, 255, 0.1);
.row-label {
width: 100px;
color: rgba(255, 255, 255, 0.6);
font-size: 14px;
}
.row-value {
flex: 1;
color: rgba(255, 255, 255, 0.9);
font-size: 14px;
&.name {
color: #40a9ff;
width: auto;
flex: none;
margin-right: 8px;
}
&.phone {
color: #40a9ff;
width: auto;
flex: none;
margin-right: 16px;
}
&.frequency {
color: rgba(255, 255, 255, 0.6);
width: auto;
flex: none;
}
}
.location-icon {
color: #40a9ff;
font-size: 16px;
cursor: pointer;
margin-left: 8px;
}
}
}
.info-item {
flex: 1;
display: flex;
flex-direction: column;
gap: 4px;
.info-label {
color: rgba(255, 255, 255, 0.6);
font-size: 13px;
}
.info-value {
color: rgba(255, 255, 255, 0.9);
font-size: 14px;
font-weight: 500;
}
}
.info-block {
margin-bottom: 16px;
padding: 12px;
background: rgba(64, 169, 255, 0.05);
border-radius: 4px;
.block-title {
color: rgba(255, 255, 255, 0.6);
font-size: 13px;
margin-bottom: 8px;
}
.block-content {
color: rgba(255, 255, 255, 0.9);
font-size: 14px;
line-height: 1.6;
}
}
.responsibility-list {
display: flex;
flex-direction: column;
gap: 8px;
.responsibility-item {
display: flex;
align-items: center;
gap: 8px;
.responsibility-label {
width: 140px;
color: rgba(255, 255, 255, 0.6);
font-size: 13px;
}
.responsibility-name {
color: #40a9ff;
font-size: 14px;
width: 60px;
}
.responsibility-phone {
color: #40a9ff;
font-size: 14px;
width: 120px;
}
.responsibility-frequency {
color: rgba(255, 255, 255, 0.6);
font-size: 13px;
flex: 1;
}
}
}
}
</style>

View File

@ -683,7 +683,7 @@ const processUnifiedData = (item, type) => {
return { return {
...baseData, ...baseData,
// - 使 // - 使
region: item.GL1_QXMC || "-", region: item.GL1_ZDMC || "-",
// - 使线+ // - 使线+
pointLocation: `${item.GL1_GLMC || item.GL1_GLBH || "-"} (${item.GL1_QDZH || "-"} - ${item.GL1_ZDZH || "-"})`, pointLocation: `${item.GL1_GLMC || item.GL1_GLBH || "-"} (${item.GL1_QDZH || "-"} - ${item.GL1_ZDZH || "-"})`,
// - 使 // - 使

View File

@ -19,78 +19,20 @@
<!-- 统计卡片 --> <!-- 统计卡片 -->
<div class="stats-cards"> <div class="stats-cards">
<div <div
@click="handleClick('0')" v-for="(item, index) in statsCardsData"
:key="index"
@click="handleClick(item.type)"
class="stat-card" class="stat-card"
:style="{ :style="{
backgroundImage: `url(${cardType === '0' ? selectedIcon : unselectedIcon})`, backgroundImage: `url(${cardType === item.type ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%', backgroundSize: '100% 100%',
backgroundPosition: 'center', backgroundPosition: 'center',
}" }"
> >
<div class="stat-icon"><img :src="Icon0" alt="" /></div> <div class="stat-icon"><img :src="item.icon" alt="" /></div>
<div class="stat-content"> <div class="stat-content">
<span class="stat-label">影响桥梁</span> <span class="stat-label">{{ item.label }}</span>
<span class="stat-value">(1430)</span> <span class="stat-value">{{ item.value }}</span>
</div>
</div>
<div
@click="handleClick('1')"
class="stat-card"
:style="{
backgroundImage: `url(${cardType === '1' ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="Icon1" alt="" /></div>
<div class="stat-content">
<span class="stat-label">影响边坡</span>
<span class="stat-value">(933)</span>
</div>
</div>
<div
@click="handleClick('2')"
class="stat-card"
:style="{
backgroundImage: `url(${cardType === '2' ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="Icon2" alt="" /></div>
<div class="stat-content">
<span class="stat-label">影响隧道</span>
<span class="stat-value">(1033)</span>
</div>
</div>
<div
@click="handleClick('3')"
class="stat-card"
:style="{
backgroundImage: `url(${cardType === '3' ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="Icon3" alt="" /></div>
<div class="stat-content">
<span class="stat-label">影响项目</span>
<span class="stat-value">(832)</span>
</div>
</div>
<div
@click="handleClick('4')"
class="stat-card"
:style="{
backgroundImage: `url(${cardType === '4' ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="Icon4" alt="" /></div>
<div class="stat-content">
<span class="stat-label">影响路段</span>
<span class="stat-value">(832)</span>
</div> </div>
</div> </div>
</div> </div>
@ -115,7 +57,8 @@
</div> --> </div> -->
<div class="filter-item"> <div class="filter-item">
<span class="filter-label">影响点等级</span> <span class="filter-label">影响点等级</span>
<el-select :teleported="false" <el-select
:teleported="false"
v-model="filterForm.pointLevel" v-model="filterForm.pointLevel"
placeholder="影响点等级" placeholder="影响点等级"
class="filter-select" class="filter-select"
@ -130,7 +73,8 @@
</div> </div>
<div class="filter-item"> <div class="filter-item">
<span class="filter-label">是否回应</span> <span class="filter-label">是否回应</span>
<el-select :teleported="false" <el-select
:teleported="false"
v-model="filterForm.isResponded" v-model="filterForm.isResponded"
placeholder="是否回应" placeholder="是否回应"
class="filter-select" class="filter-select"
@ -148,9 +92,7 @@
<!-- 影响点等级列插槽 --> <!-- 影响点等级列插槽 -->
<template #pointLevel="{ row }"> <template #pointLevel="{ row }">
<span class="level-tag" :class="row.levelClass">{{ <span class="level-tag" :class="row.levelClass">{{ row.pointLevel }}</span>
row.pointLevel
}}</span>
</template> </template>
<!-- 交通主管部门负责人列插槽 --> <!-- 交通主管部门负责人列插槽 -->
@ -160,11 +102,7 @@
<span style="margin-right: 5px">{{ row.trafficDept.name }}</span> <span style="margin-right: 5px">{{ row.trafficDept.name }}</span>
<img <img
class="response-icon" class="response-icon"
:src=" :src="row.trafficDept.isResponded ? row.trafficDept.img : row.trafficDept.img"
row.trafficDept.isResponded
? row.trafficDept.img
: row.trafficDept.img
"
alt alt
/> />
</div> </div>
@ -197,11 +135,11 @@
</template> </template>
<!-- 回应状态列插槽 --> <!-- 回应状态列插槽 -->
<template #responseStatus="{ row }"> <!-- <template #responseStatus="{ row }">
<span class="response-status" :class="row.responseClass">{{ <span class="response-status" :class="row.responseClass">{{
row.responseStatus row.responseStatus
}}</span> }}</span>
</template> </template> -->
<!-- 最新催告时间列插槽 --> <!-- 最新催告时间列插槽 -->
<template #urgeTime="{ row }"> <template #urgeTime="{ row }">
@ -219,25 +157,22 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch, onMounted } from 'vue';
import { Close, ArrowLeft, ArrowRight } from "@element-plus/icons-vue"; import { Close, ArrowLeft, ArrowRight } from '@element-plus/icons-vue';
import { import { pointTypeOptions, pointLevelOptions, isRespondedOptions } from '../component/index.js';
pointTypeOptions, import baseDialog from '../component/baseDialog.vue';
pointLevelOptions, import { request } from '@/utils/request.js';
isRespondedOptions,
} from "../component/index.js";
import baseDialog from "../component/baseDialog.vue";
import respondedIcon from "../../../assets/xiangying/有回应@2x.png"; import respondedIcon from '../../../assets/xiangying/有回应@2x.png';
import notRespondedIcon from "../../../assets/xiangying/无回应@2x.png"; import notRespondedIcon from '../../../assets/xiangying/无回应@2x.png';
import selectedIcon from "../../../assets/xiangying/选中bg@2x.png"; import selectedIcon from '../../../assets/xiangying/选中bg@2x.png';
import unselectedIcon from "../../../assets/xiangying/未选中bg@2x.png"; import unselectedIcon from '../../../assets/xiangying/未选中bg@2x.png';
import Icon0 from "../../../assets/xiangying/选中@2x.png"; import Icon0 from '../../../assets/xiangying/选中@2x.png';
import Icon1 from "../../../assets/xiangying/未选中1@2x.png"; import Icon1 from '../../../assets/xiangying/未选中1@2x.png';
import Icon2 from "../../../assets/xiangying/未选中2@2x.png"; import Icon2 from '../../../assets/xiangying/未选中2@2x.png';
import Icon3 from "../../../assets/xiangying/未选中3@2x.png"; import Icon3 from '../../../assets/xiangying/未选中3@2x.png';
import Icon4 from "../../../assets/xiangying/未选中4@2x.png"; import Icon4 from '../../../assets/xiangying/未选中4@2x.png';
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -246,104 +181,113 @@ const props = defineProps({
}, },
}); });
const emit = defineEmits(["update:visible", "close", "detail"]); const emit = defineEmits(['update:visible', 'close', 'detail']);
// //
const filterForm = ref({ const filterForm = ref({
pointType: "", pointType: '',
pointLevel: "", pointLevel: '',
isResponded: "", isResponded: '',
}); });
const cardType = ref("0"); const cardType = ref('0');
//
const statsCardsData = ref([
{ type: '桥梁', label: '影响桥梁', value: 0, icon: Icon0 },
{ type: '路段', label: '影响路段', value: 0, icon: Icon4 },
{ type: '隧道', label: '影响隧道', value: 0, icon: Icon2 },
{ type: '边坡', label: '影响边坡', value: 0, icon: Icon1 },
{ type: '项目', label: '影响项目', value: 0, icon: Icon3 },
]);
// //
const tableColumns = ref([ const tableColumns = ref([
{ prop: "id", label: "序号", width: "50px" }, { prop: 'id', label: '序号', width: '50px' },
{ prop: "pointType", label: "影响点类型", width: "80px" }, { prop: 'pointType', label: '影响点类型', width: '80px' },
{ prop: "pointLocation", label: "影响点位置", width: "150px" }, { prop: 'pointLocation', label: '影响点位置', width: '150px' },
{ {
prop: "pointLevel", prop: 'pointLevel',
label: "影响点等级", label: '影响点等级',
width: "90px", width: '90px',
slot: "pointLevel", slot: 'pointLevel',
}, },
{ prop: "checkCount", label: "查次数", width: "60px" }, { prop: 'checkCount', label: '查次数', width: '60px' },
{ {
prop: "trafficDept", prop: 'trafficDept',
label: "交通主管部门负责人", label: '交通主管部门负责人',
width: "120px", width: '120px',
slot: "trafficDept", slot: 'trafficDept',
}, },
{ prop: "roadOrg", label: "公路机构责任人", width: "110px", slot: "roadOrg" }, { prop: 'roadOrg', label: '公路机构责任人', width: '110px', slot: 'roadOrg' },
{ {
prop: "maintenance", prop: 'maintenance',
label: "养护站负责人", label: '养护站负责人',
width: "110px", width: '110px',
slot: "maintenance", slot: 'maintenance',
}, },
{ prop: "roadKeeper", label: "护路员", width: "80px", slot: "roadKeeper" }, { prop: 'roadKeeper', label: '护路员', width: '80px', slot: 'roadKeeper' },
{ // {
prop: "responseStatus", // prop: "responseStatus",
label: "回应状态", // label: "",
width: "70px", // width: "70px",
slot: "responseStatus", // slot: "responseStatus",
}, // },
{ prop: "urgeTime", label: "最新催告时间", width: "110px", slot: "urgeTime" }, { prop: 'urgeTime', label: '最新催告时间', width: '110px', slot: 'urgeTime' },
{ prop: "operation", label: "操作", width: "50px", slot: "operation" }, { prop: 'operation', label: '操作', width: '50px', slot: 'operation' },
]); ]);
// //
const tableData = ref([ const tableData = ref([
{ {
id: 1, id: 1,
pointType: "边坡", pointType: '边坡',
pointLocation: "武汉-大理(K1452+951至K1462+209)", pointLocation: '武汉-大理(K1452+951至K1462+209)',
pointLevel: "一般隐患", pointLevel: '一般隐患',
levelClass: "level-normal", levelClass: 'level-normal',
checkCount: 2, checkCount: 2,
trafficDept: { trafficDept: {
name: "罗宸", name: '罗宸',
phone: "17623865172", phone: '17623865172',
img: respondedIcon, img: respondedIcon,
isResponded: true, isResponded: true,
}, },
roadOrg: { roadOrg: {
name: "李海平", name: '李海平',
phone: "1372386532", phone: '1372386532',
img: notRespondedIcon, img: notRespondedIcon,
isResponded: false, isResponded: false,
}, },
maintenance: { maintenance: {
name: "苏祖兵", name: '苏祖兵',
phone: "13594331090", phone: '13594331090',
img: notRespondedIcon, img: notRespondedIcon,
isResponded: false, isResponded: false,
}, },
roadKeeper: { roadKeeper: {
name: "凌承礼", name: '凌承礼',
phone: "1592393704", phone: '1592393704',
img: respondedIcon, img: respondedIcon,
isResponded: true, isResponded: true,
}, },
responseStatus: "已回应", responseStatus: '已回应',
responseClass: "status-responded", responseClass: 'status-responded',
urgeTime: { date: "2026-03-28", time: "12:30:00" }, urgeTime: { date: '2026-03-28', time: '12:30:00' },
}, },
{ {
id: 12, id: 12,
pointType: "边坡", pointType: '边坡',
pointLocation: "武汉-大理(K1452+951至K1462+209)", pointLocation: '武汉-大理(K1452+951至K1462+209)',
pointLevel: "一般隐患", pointLevel: '一般隐患',
levelClass: "level-normal", levelClass: 'level-normal',
checkCount: 2, checkCount: 2,
trafficDept: { name: "罗宸", phone: "17623865172" }, trafficDept: { name: '罗宸', phone: '17623865172' },
roadOrg: { name: "李海平", phone: "1372386532" }, roadOrg: { name: '李海平', phone: '1372386532' },
maintenance: { name: "苏祖兵", phone: "13594331090" }, maintenance: { name: '苏祖兵', phone: '13594331090' },
roadKeeper: { name: "凌承礼", phone: "1592393704" }, roadKeeper: { name: '凌承礼', phone: '1592393704' },
responseStatus: "已回应", responseStatus: '已回应',
responseClass: "status-responded", responseClass: 'status-responded',
urgeTime: { date: "2026-03-28", time: "12:30:00" }, urgeTime: { date: '2026-03-28', time: '12:30:00' },
}, },
]); ]);
tableData.value.push(...tableData.value); tableData.value.push(...tableData.value);
@ -356,49 +300,90 @@ const total = ref(36);
// //
const handleClose = () => { const handleClose = () => {
emit("update:visible", false); emit('update:visible', false);
emit("close"); emit('close');
}; };
// //
const handleClick = (type) => { const handleClick = type => {
cardType.value = type; cardType.value = type;
}; };
//
const loadBarChartData = async () => {
try {
const res = await request({
url: '/snow-ops-platform/weather-warning/affected-count',
method: 'GET',
});
if (res.code == '00000') {
const data = res.data;
if (data && Array.isArray(data)) {
//
const nameMap = {
'road-section': '路段',
bridge: '桥梁',
tunnel: '隧道',
slope: '边坡',
project: '项目',
Road: '路段',
Bridge: '桥梁',
Tunnel: '隧道',
Slope: '边坡',
Project: '项目',
};
statsCardsData.value.forEach(item => {
data.forEach(stat => {
if (stat.extension == item.type) {
item.value = stat.count || 0;
}
});
});
}
}
} catch (error) {
console.error('加载柱状图数据失败:', error);
}
};
// base-dialog // base-dialog
// //
const handleDetail = (item) => { const handleDetail = item => {
emit("detail", item); emit('detail', item);
}; };
// //
const handleSizeChange = (val) => { const handleSizeChange = val => {
pageSize.value = val; pageSize.value = val;
fetchData(); fetchData();
}; };
const handleCurrentChange = (val) => { const handleCurrentChange = val => {
currentPage.value = val; currentPage.value = val;
fetchData(); fetchData();
}; };
// //
const fetchData = () => { const fetchData = () => {
console.log("获取第", currentPage.value, "页数据"); console.log('获取第', currentPage.value, '页数据');
// API // API
}; };
// visible // visible
watch( watch(
() => props.visible, () => props.visible,
(newVal) => { newVal => {
if (newVal) { if (newVal) {
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
} }
}, }
); );
onMounted(() => {
//
loadBarChartData();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,7 +1,7 @@
<template> <template>
<base-dialog <base-dialog
v-model:visible="props.visible" v-model:visible="props.visible"
title="潼南基本信息表" :title="props.allCountyData.name + '基本信息表'"
:table-data="tableData" :table-data="tableData"
:table-columns="tableColumns" :table-columns="tableColumns"
:table-height="320" :table-height="320"
@ -32,70 +32,83 @@
<!-- 驻地名称列插槽 --> <!-- 驻地名称列插槽 -->
<template #stationName="{ row }"> <template #stationName="{ row }">
<el-tooltip :content="row.stationName" placement="top" :show-after="500"> <el-tooltip :content="row.stationName" placement="top" :show-after="500">
<span class="station-name-text" @click="handleStationNameClick(row)">{{ row.stationName }}</span> <span class="station-name-text" @click="handleStationNameClick(row)">
{{ row.stationName }}
</span>
</el-tooltip> </el-tooltip>
</template> </template>
</base-dialog> </base-dialog>
</template> </template>
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from 'vue';
import { VideoCamera, Microphone, Phone } from "@element-plus/icons-vue"; import { VideoCamera, Microphone, Phone } from '@element-plus/icons-vue';
import baseDialog from "../component/baseDialog.vue"; import baseDialog from '../component/baseDialog.vue';
const props = defineProps({ const props = defineProps({
visible: { visible: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
allCountyData: {
type: Object,
default: () => {},
},
tongnanInfoItemData: {
type: Object,
default: () => ({
name: '',
}),
},
}); });
const emit = defineEmits(["update:visible", "close", "video", "voice", "call", "stationNameClick"]); const emit = defineEmits(['update:visible', 'close', 'video', 'voice', 'call', 'stationNameClick']);
// //
const tableColumns = ref([ const tableColumns = ref([
{ prop: "id", label: "序号", width: "60px" }, { prop: 'id', label: '序号', width: '60px' },
{ prop: "region", label: "区县/镇街", width: "140px" }, { prop: 'region', label: '区县/镇街', width: '140px' },
{ prop: "name", label: "姓名", width: "100px" }, { prop: 'name', label: '姓名', width: '100px' },
{ prop: "phone", label: "电话", width: "120px" }, { prop: 'phone', label: '电话', width: '120px' },
{ prop: "stationName", label: "驻地名称", width: "180px", slot: "stationName" }, { prop: 'stationName', label: '驻地名称', width: '180px', slot: 'stationName' },
{ prop: "type", label: "类型", width: "auto" }, { prop: 'type', label: '类型', width: 'auto' },
{ prop: "operation", label: "调度", width: "140px", slot: "operation" }, { prop: 'operation', label: '调度', width: '140px', slot: 'operation' },
]); ]);
// //
const tableData = ref([ const tableData = ref([
{ {
id: 1, id: 1,
region: "沙坪坝区", region: '沙坪坝区',
name: "赵海浪", name: '赵海浪',
phone: "18623520688", phone: '18623520688',
stationName: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部", stationName: '沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部',
type: "交通主管部门", type: '交通主管部门',
}, },
{ {
id: 2, id: 2,
region: "沙坪坝区", region: '沙坪坝区',
name: "府效能", name: '府效能',
phone: "18623520688", phone: '18623520688',
stationName: "沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部", stationName: '沙坪坝区S545茅山峡公路桥新建工程渝黔铁路扩能改造工程项目经理部',
type: "公路机构", type: '公路机构',
}, },
{ {
id: 3, id: 3,
region: "万州区柏梓镇", region: '万州区柏梓镇',
name: "王鑫", name: '王鑫',
phone: "18623520688", phone: '18623520688',
stationName: "万州区项目经理部", stationName: '万州区项目经理部',
type: "公路机构", type: '公路机构',
}, },
{ {
id: 4, id: 4,
region: "万州区柏梓镇", region: '万州区柏梓镇',
name: "王鑫", name: '王鑫',
phone: "18623520688", phone: '18623520688',
stationName: "万州区项目经理部", stationName: '万州区项目经理部',
type: "公路机构", type: '公路机构',
}, },
]); ]);
@ -124,52 +137,52 @@ const visiblePages = computed(() => {
// //
const handleClose = () => { const handleClose = () => {
emit("update:visible", false); emit('update:visible', false);
emit("close"); emit('close');
}; };
// base-dialog // base-dialog
// //
const handleVideo = (item) => { const handleVideo = item => {
emit("video", item); emit('video', item);
}; };
const handleVoice = (item) => { const handleVoice = item => {
emit("voice", item); emit('voice', item);
}; };
const handleCall = (item) => { const handleCall = item => {
emit("call", item); emit('call', item);
}; };
// //
const handleStationNameClick = (item) => { const handleStationNameClick = item => {
emit("stationNameClick", item); emit('stationNameClick', item);
}; };
// //
const handleSizeChange = (size) => { const handleSizeChange = size => {
pageSize.value = size; pageSize.value = size;
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
}; };
const handleCurrentChange = (page) => { const handleCurrentChange = page => {
currentPage.value = page; currentPage.value = page;
fetchData(); fetchData();
}; };
// //
const fetchData = () => { const fetchData = () => {
console.log("获取第", currentPage.value, "页数据"); console.log('获取第', currentPage.value, '页数据');
// API // API
}; };
// visible // visible
watch( watch(
() => props.visible, () => props.visible,
(newVal) => { newVal => {
if (newVal) { if (newVal) {
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
@ -189,7 +202,7 @@ watch(
width: 28px; width: 28px;
height: 28px; height: 28px;
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;

View File

@ -0,0 +1,238 @@
<template>
<base-dialog
v-model:visible="props.visible"
:title="`${props.allCountyData.name}建设项目责任人详情`"
:table-data="tableData"
:table-columns="tableColumns"
:table-height="350"
:total="total"
:current-page="currentPage"
:page-size="pageSize"
:z-index="1000"
:max-width="1100"
:show-filter="false"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@close="handleClose"
>
<!-- 调度列插槽 -->
<template #dispatch="{ row }">
<div class="dispatch-actions">
<div class="action-btns">
<div class="action-btn" @click="handleView(row)">
<el-icon><VideoCamera /></el-icon>
</div>
<div class="action-btn" @click="handleVoice(row)">
<el-icon><Microphone /></el-icon>
</div>
<div class="action-btn" @click="handleCall(row)">
<el-icon><Phone /></el-icon>
</div>
</div>
</div>
</template>
</base-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
import baseDialog from '../component/baseDialog.vue';
import {
Close,
VideoCamera,
Microphone,
Phone,
ArrowLeft,
ArrowRight,
User,
OfficeBuilding,
MapLocation,
} from '@element-plus/icons-vue';
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
allCountyData: {
type: Object,
default: () => {},
},
});
const emit = defineEmits(['update:visible', 'close']);
//
const tableColumns = ref([
{ prop: 'id', label: '序号', width: '' },
{ prop: 'district', label: '区县/镇街', width: '' },
{ prop: 'totalCount', label: '总人数', width: '' },
{ prop: 'whistleblower', label: '吹哨人', width: '' },
{ prop: 'constructionUnit', label: '建设单位包保责任人', width: '' },
{ prop: 'constructionDept', label: '施工单位包保责任人', width: '' },
{ prop: 'stationUnit', label: '驻地包保责任人', width: '' },
{ prop: 'districtUnit', label: '区县级包保责任人', width: '' },
{ prop: 'cityUnit', label: '市级包保责任人', width: '' },
{ prop: 'dispatch', label: '调度', width: '', slot: 'dispatch' },
]);
//
const tableData = ref([
{
id: 1,
district: '万州区',
totalCount: 6,
whistleblower: 2,
constructionUnit: '罗宸\n17623865172',
constructionDept: '李海平\n1372386532',
stationUnit: '苏祖兵\n13594331090',
districtUnit: '凌承礼\n1592393704',
cityUnit: '周刚\n1892395467',
},
{
id: 2,
district: '涪陵区',
totalCount: 8,
whistleblower: 3,
constructionUnit: '张三\n13800138000',
constructionDept: '李四\n13900139000',
stationUnit: '王五\n13700137000',
districtUnit: '赵六\n13600136000',
cityUnit: '孙七\n13500135000',
},
{
id: 3,
district: '渝中区',
totalCount: 5,
whistleblower: 2,
constructionUnit: '周八\n13400134000',
constructionDept: '吴九\n13300133000',
stationUnit: '郑十\n13200132000',
districtUnit: '钱十一\n13100131000',
cityUnit: '陈十二\n13000130000',
},
{
id: 4,
district: '江北区',
totalCount: 7,
whistleblower: 3,
constructionUnit: '刘一\n12900129000',
constructionDept: '黄二\n12800128000',
stationUnit: '林三\n12700127000',
districtUnit: '杨四\n12600126000',
cityUnit: '何五\n12500125000',
},
{
id: 5,
district: '沙坪坝区',
totalCount: 6,
whistleblower: 2,
constructionUnit: '高六\n12400124000',
constructionDept: '马七\n12300123000',
stationUnit: '罗八\n12200122000',
districtUnit: '梁九\n12100121000',
cityUnit: '宋十\n12000120000',
},
]);
const total = ref(36);
const currentPage = ref(1);
const pageSize = ref(10);
//
const handleClose = () => {
emit('update:visible', false);
emit('close');
};
//
const handleSizeChange = val => {
pageSize.value = val;
fetchData();
};
const handleCurrentChange = val => {
currentPage.value = val;
fetchData();
};
//
const fetchData = () => {
console.log('获取第', currentPage.value, '页数据');
// API
};
//
const handleView = item => {
console.log('查看视频:', item);
};
const handleVoice = item => {
console.log('语音通话:', item);
};
const handleCall = item => {
console.log('拨打电话:', item);
};
// visible
watch(
() => props.visible,
newVal => {
if (newVal) {
currentPage.value = 1;
fetchData();
}
}
);
</script>
<style lang="scss" scoped>
.dispatch-actions {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
.dispatch-icon {
width: 24px;
height: 24px;
cursor: pointer;
transition: transform 0.2s;
&:hover {
transform: scale(1.1);
}
}
}
:deep(.el-table .cell) {
white-space: pre-line;
line-height: 1.5;
}
//
.action-btns {
display: flex;
justify-content: center;
gap: 8px;
.action-btn {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(64, 169, 255, 0.15);
border-radius: 2px;
color: #40a9ff;
cursor: pointer;
transition: all 0.3s;
&:hover {
background-color: rgba(64, 169, 255, 0.3);
transform: scale(1.1);
}
}
}
</style>

View File

@ -1,7 +1,7 @@
<template> <template>
<base-dialog <base-dialog
v-model:visible="props.visible" v-model:visible="props.visible"
:title="props.allCountyData.name + '建设责任人明细'" :title="props.allCountyData.name + '建设项目责任人明细'"
:table-data="tableData" :table-data="tableData"
:table-columns="tableColumns" :table-columns="tableColumns"
:table-height="400" :table-height="400"
@ -22,8 +22,8 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from 'vue';
import baseDialog from "../component/baseDialog.vue"; import baseDialog from '../component/baseDialog.vue';
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -33,32 +33,38 @@ const props = defineProps({
allCountyData: { allCountyData: {
type: Object, type: Object,
default: () => ({ default: () => ({
name: "", name: '',
}),
},
tongnanInfoItemData: {
type: Object,
default: () => ({
name: '',
}), }),
}, },
}); });
const emit = defineEmits(["update:visible", "close", "detail"]); const emit = defineEmits(['update:visible', 'close', 'detail']);
// //
const tableColumns = ref([ const tableColumns = ref([
{ prop: "id", label: "序号", width: "" }, { prop: 'id', label: '序号', width: '' },
{ prop: "region", label: "区县/镇街", width: "" }, { prop: 'region', label: '区县/镇街', width: '' },
{ prop: "totalCount", label: "总人数", width: "" }, { prop: 'totalCount', label: '总人数', width: '' },
{ prop: "whistleblower", label: "吹哨人", width: "" }, { prop: 'whistleblower', label: '吹哨人', width: '' },
{ prop: "constructionUnit", label: "建设单位包保责任人", width: "" }, { prop: 'constructionUnit', label: '建设单位包保责任人', width: '' },
{ prop: "contractorUnit", label: "施工单位包保责任人", width: "" }, { prop: 'contractorUnit', label: '施工单位包保责任人', width: '' },
{ prop: "stationed", label: "驻地包保责任人", width: "" }, { prop: 'stationed', label: '驻地包保责任人', width: '' },
{ prop: "districtLevel", label: "区县级包保责任人", width: "" }, { prop: 'districtLevel', label: '区县级包保责任人', width: '' },
{ prop: "cityLevel", label: "市级包保责任人", width: "" }, { prop: 'cityLevel', label: '市级包保责任人', width: '' },
{ prop: "operation", label: "操作", width: "60px", slot: "operation" }, { prop: 'operation', label: '操作', width: '60px', slot: 'operation' },
]); ]);
// //
const tableData = ref([ const tableData = ref([
{ {
id: 1, id: 1,
region: "万州区", region: '万州区',
totalCount: 6, totalCount: 6,
whistleblower: 2, whistleblower: 2,
constructionUnit: 2, constructionUnit: 2,
@ -69,7 +75,7 @@ const tableData = ref([
}, },
{ {
id: 2, id: 2,
region: "柏梓镇", region: '柏梓镇',
totalCount: 6, totalCount: 6,
whistleblower: 2, whistleblower: 2,
constructionUnit: 2, constructionUnit: 2,
@ -105,44 +111,44 @@ const visiblePages = computed(() => {
// //
const handleClose = () => { const handleClose = () => {
emit("update:visible", false); emit('update:visible', false);
emit("close"); emit('close');
}; };
// base-dialog // base-dialog
// //
const handleDetail = (item) => { const handleDetail = item => {
emit("detail", item); emit('detail', item);
}; };
// //
const handleSizeChange = (size) => { const handleSizeChange = size => {
pageSize.value = size; pageSize.value = size;
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
}; };
const handleCurrentChange = (page) => { const handleCurrentChange = page => {
currentPage.value = page; currentPage.value = page;
fetchData(); fetchData();
}; };
// //
const fetchData = () => { const fetchData = () => {
console.log("获取第", currentPage.value, "页数据"); console.log('获取第', currentPage.value, '页数据');
// API // API
}; };
// visible // visible
watch( watch(
() => props.visible, () => props.visible,
(newVal) => { newVal => {
if (newVal) { if (newVal) {
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
} }
}, }
); );
</script> </script>

View File

@ -22,8 +22,8 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from 'vue';
import baseDialog from "../component/baseDialog.vue"; import baseDialog from '../component/baseDialog.vue';
const props = defineProps({ const props = defineProps({
visible: { visible: {
@ -33,30 +33,30 @@ const props = defineProps({
allCountyData: { allCountyData: {
type: Object, type: Object,
default: () => ({ default: () => ({
name: "", name: '',
}), }),
}, },
}); });
const emit = defineEmits(["update:visible", "close", "view"]); const emit = defineEmits(['update:visible', 'close', 'view', 'itemdata']);
// //
const tableColumns = ref([ const tableColumns = ref([
{ prop: "id", label: "序号", width: "60px" }, { prop: 'id', label: '序号', width: '60px' },
{ prop: "district", label: "区县", width: "100px" }, { prop: 'district', label: '区县', width: '100px' },
{ prop: "totalCount", label: "总人数", width: "80px" }, { prop: 'totalCount', label: '总人数', width: '80px' },
{ prop: "trafficDept", label: "交通主管部门责任人", width: "140px" }, { prop: 'trafficDept', label: '交通主管部门责任人', width: '140px' },
{ prop: "roadOrg", label: "公路机构责任人", width: "120px" }, { prop: 'roadOrg', label: '公路机构责任人', width: '120px' },
{ prop: "maintenance", label: "养护站道班责任人", width: "140px" }, { prop: 'maintenance', label: '养护站道班责任人', width: '140px' },
{ prop: "roadKeeper", label: "护路员", width: "80px" }, { prop: 'roadKeeper', label: '护路员', width: '80px' },
{ prop: "operation", label: "操作", width: "auto", slot: "operation" }, { prop: 'operation', label: '操作', width: 'auto', slot: 'operation' },
]); ]);
// //
const tableData = ref([ const tableData = ref([
{ {
id: 1, id: 1,
district: "潼南", district: '潼南',
totalCount: 128, totalCount: 128,
trafficDept: 2, trafficDept: 2,
roadOrg: 3, roadOrg: 3,
@ -65,7 +65,7 @@ const tableData = ref([
}, },
{ {
id: 2, id: 2,
district: "万州", district: '万州',
totalCount: 96, totalCount: 96,
trafficDept: 1, trafficDept: 1,
roadOrg: 2, roadOrg: 2,
@ -74,7 +74,7 @@ const tableData = ref([
}, },
{ {
id: 3, id: 3,
district: "沙坪坝", district: '沙坪坝',
totalCount: 156, totalCount: 156,
trafficDept: 3, trafficDept: 3,
roadOrg: 4, roadOrg: 4,
@ -83,7 +83,7 @@ const tableData = ref([
}, },
{ {
id: 4, id: 4,
district: "渝中", district: '渝中',
totalCount: 64, totalCount: 64,
trafficDept: 1, trafficDept: 1,
roadOrg: 2, roadOrg: 2,
@ -117,44 +117,48 @@ const visiblePages = computed(() => {
// //
const handleClose = () => { const handleClose = () => {
emit("update:visible", false); emit('update:visible', false);
emit("close"); emit('close');
}; };
// base-dialog // base-dialog
// //
const handleView = (item) => { const handleView = item => {
emit("view", item); emit('view');
emit('itemdata', {
...item,
allCountyData: props.allCountyData,
});
}; };
// //
const handleSizeChange = (size) => { const handleSizeChange = size => {
pageSize.value = size; pageSize.value = size;
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
}; };
const handleCurrentChange = (page) => { const handleCurrentChange = page => {
currentPage.value = page; currentPage.value = page;
fetchData(); fetchData();
}; };
// //
const fetchData = () => { const fetchData = () => {
console.log("获取第", currentPage.value, "页数据"); console.log('获取第', currentPage.value, '页数据');
// API // API
}; };
// visible // visible
watch( watch(
() => props.visible, () => props.visible,
(newVal) => { newVal => {
if (newVal) { if (newVal) {
currentPage.value = 1; currentPage.value = 1;
fetchData(); fetchData();
} }
}, }
); );
</script> </script>

View File

@ -8,13 +8,15 @@
:class="{ active: activeIndex === index }" :class="{ active: activeIndex === index }"
@click="handleClick(item, index)" @click="handleClick(item, index)"
> >
<div class="nav-icon-box" :ref="(el) => setNavIconRef(el, index)"> <div class="nav-icon-box" :ref="el => setNavIconRef(el, index)">
<!-- <i :class="item.icon"></i> --> <!-- <i :class="item.icon"></i> -->
<img :src="activeIndex === index ? item.icon1 : item.icon" alt="" /> <img :src="activeIndex === index ? item.icon1 : item.icon" alt="" />
</div> </div>
<div class="nav-label">{{ item.label }}</div> <div class="nav-label">{{ item.label }}</div>
</div> </div>
</div> </div>
<!-- 气象预警监测表格组件 -->
<WeatherWarningTable ref="weatherWarningTableRef" @clearFilters="handleClearFilters" />
<!-- 涉灾隐患点图片弹窗 --> <!-- 涉灾隐患点图片弹窗 -->
<div v-if="showHazardPopup" class="hazard-popup" :style="popupStyle"> <div v-if="showHazardPopup" class="hazard-popup" :style="popupStyle">
<div class="hazard-popup-content"> <div class="hazard-popup-content">
@ -30,11 +32,7 @@
</div> </div>
</div> </div>
<!-- 路段图片弹窗 --> <!-- 路段图片弹窗 -->
<div <div v-if="showRoadPopup" class="hazard-popup road-popup" :style="roadPopupStyle">
v-if="showRoadPopup"
class="hazard-popup road-popup"
:style="roadPopupStyle"
>
<div class="hazard-popup-content"> <div class="hazard-popup-content">
<div <div
v-for="(item, index) in roadItems" v-for="(item, index) in roadItems"
@ -47,172 +45,98 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 气象预警监测表格 -->
<div class="weather-warning-wrapper">
<div class="weather-warning-panel">
<img
class="clear-icon"
src="../../assets/RiskWarning_img/清除icon@2x.png"
alt=""
@click="clearFilters"
/>
<div class="panel-header">
<div class="header-title">气象预警监测</div>
<div class="filter-tags">
<label class="tag">
<input type="checkbox" v-model="filters.red" />
<span class="">红色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.blue" />
<span class="">蓝色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.orange" />
<span class="">橙色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.yellow" />
<span class="">黄色预警</span>
</label>
</div>
</div>
<div class="table-container">
<el-table
:data="filteredData"
height="100%"
style="width: 100%; background: transparent"
:header-cell-style="headerCellStyle"
:cell-style="cellStyle"
:row-class-name="rowClassName"
>
<el-table-column prop="time" label="预警时间" min-width="vw(140)" />
<el-table-column
prop="type"
label="类型"
min-width="vw(80)"
align="center"
/>
<el-table-column
label="预警等级"
min-width="vw(100)"
align="center"
>
<template #default="{ row }">
<div class="warning-level">
<img
:src="
row.levelClass === 'red'
? redIcon
: row.levelClass === 'blue'
? blueIcon
: row.levelClass === 'orange'
? orangeIcon
: yellowIcon
"
alt=""
/>
<span class="ml_10">{{ row.level }}</span>
</div>
</template>
</el-table-column>
<el-table-column
prop="district"
label="预警区县"
min-width="vw(80)"
/>
</el-table>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue"; import { ref, computed, nextTick } from 'vue';
import { ElTable } from "element-plus"; import WeatherWarningTable from './component/WeatherWarningTable.vue';
import orangeIcon from "../../assets/RiskWarning_img/橙色@2x.png";
import yellowIcon from "../../assets/RiskWarning_img/黄色@2x.png";
import redIcon from "../../assets/RiskWarning_img//红色@2x.png";
import blueIcon from "../../assets/RiskWarning_img/蓝色@2x.png";
import warningIconIcon from "../../assets/RiskWarning_img/风险预警icon@2x.png"; import warningIconIcon from '../../assets/RiskWarning_img/风险预警icon@2x.png';
import tunnelIconIcon from "../../assets/RiskWarning_img/隧道icon@2x.png"; 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 teamIconIcon from '../../assets/RiskWarning_img/队伍icon@2x.png';
import hazardIconIconIcon from "../../assets/RiskWarning_img/隐患点icon@2x.png"; import hazardIconIconIcon 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"; import teamIconIcon1 from '../../assets/RiskWarning_img/队伍icon1@2x.png';
import hazardIconIcon from "../../assets/RiskWarning_img/隐患点icon1@2x.png"; import hazardIconIcon from '../../assets/RiskWarning_img/隐患点icon1@2x.png';
import hazardIconIcon1 from "../../assets/MaMap_img/一般路内隐患点@2x.png"; import hazardIconIcon1 from '../../assets/MaMap_img/一般路内隐患点@2x.png';
import hazardIconIcon2 from "../../assets/MaMap_img/一般路外隐患点@2x.png"; import hazardIconIcon2 from '../../assets/MaMap_img/一般路外隐患点@2x.png';
import hazardIconIcon3 from "../../assets/MaMap_img/较大路内隐患点@2x.png"; import hazardIconIcon3 from '../../assets/MaMap_img/较大路内隐患点@2x.png';
import hazardIconIcon4 from "../../assets/MaMap_img/较大路外隐患点@2x.png"; import hazardIconIcon4 from '../../assets/MaMap_img/较大路外隐患点@2x.png';
import hazardIconIcon5 from "../../assets/MaMap_img/重大路内隐患点@2x.png"; import hazardIconIcon5 from '../../assets/MaMap_img/重大路内隐患点@2x.png';
import hazardIconIcon6 from "../../assets/MaMap_img/重大路外隐患点@2x.png"; import hazardIconIcon6 from '../../assets/MaMap_img/重大路外隐患点@2x.png';
import tunnelLineIcon3 from "../../assets/MaMap_img/高风险路段@2x.png"; import tunnelLineIcon3 from '../../assets/MaMap_img/高风险路段@2x.png';
import tunnelLineIcon2 from "../../assets/MaMap_img/较高风险路段@2x.png"; import tunnelLineIcon2 from '../../assets/MaMap_img/较高风险路段@2x.png';
import tunnelLineIcon1 from "../../assets/MaMap_img/中风险路段@2x.png"; import tunnelLineIcon1 from '../../assets/MaMap_img/中风险路段@2x.png';
import tunnelLineIcon from "../../assets/MaMap_img/线路icon定位@2x.png"; import tunnelLineIcon from '../../assets/MaMap_img/线路icon定位@2x.png';
const emit = defineEmits([
'changeActiveIndex',
'clearMapMarkers',
'hazardItemClick',
'roadItemClick',
'showHazardPopupfn',
]);
const activeIndex = ref(-1); const activeIndex = ref(-1);
const menuItems = [ const menuItems = [
{ {
label: "涉灾隐患点", label: '涉灾隐患点',
icon: "icon-hazard", icon: 'icon-hazard',
iconClass: "hazard", iconClass: 'hazard',
icon: hazardIconIconIcon, icon: hazardIconIconIcon,
icon1: hazardIconIcon, icon1: hazardIconIcon,
}, },
{ {
label: "路段", label: '路段',
icon: "icon-road", icon: 'icon-road',
iconClass: "road", iconClass: 'road',
icon: roadIconIcon, icon: roadIconIcon,
icon1: roadIconIcon1, icon1: roadIconIcon1,
}, },
{ {
label: "项目", label: '项目',
icon: "icon-warning", icon: 'icon-warning',
iconClass: "warning", iconClass: 'warning',
icon: warningIconIcon, icon: warningIconIcon,
icon1: warningIconIcon1, icon1: warningIconIcon1,
}, },
{ {
label: "隧道", label: '隧道',
icon: "icon-tunnel", icon: 'icon-tunnel',
iconClass: "tunnel", iconClass: 'tunnel',
icon: tunnelIconIcon, icon: tunnelIconIcon,
icon1: tunnelIconIcon1, icon1: tunnelIconIcon1,
}, },
{ {
label: "边坡", label: '边坡',
icon: "icon-slope", icon: 'icon-slope',
iconClass: "slope", iconClass: 'slope',
icon: slopeIconIcon, icon: slopeIconIcon,
icon1: slopeIconIcon1, icon1: slopeIconIcon1,
}, },
{ {
label: "桥梁", label: '桥梁',
icon: "icon-bridge", icon: 'icon-bridge',
iconClass: "bridge", iconClass: 'bridge',
icon: bridgeIconIcon, icon: bridgeIconIcon,
icon1: bridgeIconIcon1, icon1: bridgeIconIcon1,
}, },
{ {
label: "队伍", label: '队伍',
icon: "icon-team", icon: 'icon-team',
iconClass: "team", iconClass: 'team',
icon: teamIconIcon, icon: teamIconIcon,
icon1: teamIconIcon1, icon1: teamIconIcon1,
}, },
@ -225,12 +149,12 @@ const navIconRefs = ref([]);
// //
const hazardItems = ref([ const hazardItems = ref([
{ icon: hazardIconIcon5, label: "重大路内隐患点" }, { icon: hazardIconIcon5, label: '重大路内隐患点', isWithinRedLine: '是' },
{ icon: hazardIconIcon6, label: "重大路外隐患点" }, { icon: hazardIconIcon6, label: '重大路外隐患点', isWithinRedLine: '否' },
{ icon: hazardIconIcon3, label: "较大路内隐患点" }, { icon: hazardIconIcon3, label: '较大路内隐患点', isWithinRedLine: '是' },
{ icon: hazardIconIcon4, label: "较大路外隐患点" }, { icon: hazardIconIcon4, label: '较大路外隐患点', isWithinRedLine: '否' },
{ icon: hazardIconIcon1, label: "一般路内隐患点" }, { icon: hazardIconIcon1, label: '一般路内隐患点', isWithinRedLine: '是' },
{ icon: hazardIconIcon2, label: "一般路外隐患点" }, { icon: hazardIconIcon2, label: '一般路外隐患点', isWithinRedLine: '否' },
]); ]);
// //
@ -239,10 +163,10 @@ const roadPopupStyle = ref({});
// //
const roadItems = ref([ const roadItems = ref([
{ icon: tunnelLineIcon3, label: "高风险路段" }, { icon: tunnelLineIcon3, label: '高风险路段' },
{ icon: tunnelLineIcon2, label: "较高风险路段" }, { icon: tunnelLineIcon2, label: '较高风险路段' },
{ icon: tunnelLineIcon1, label: "中风险路段" }, { icon: tunnelLineIcon1, label: '中风险路段' },
{ icon: tunnelLineIcon, label: "低风险路段" }, { icon: tunnelLineIcon, label: '低风险路段' },
]); ]);
// nav-icon-boxref // nav-icon-boxref
@ -251,94 +175,12 @@ const setNavIconRef = (el, index) => {
navIconRefs.value[index] = el; navIconRefs.value[index] = el;
} }
}; };
const weatherWarningTableRef = ref(null);
//
const filters = ref({
red: false,
blue: false,
orange: false,
yellow: false,
});
//
const warningData = ref([
{
time: "2025-11-18 09:24:81",
type: "暴雨",
level: "蓝色预警",
levelClass: "blue",
district: "合川区",
},
{
time: "2025-11-12 09:24:81",
type: "冰雪",
level: "红色预警",
levelClass: "red",
district: "万州区",
},
{
time: "2025-11-12 09:24:81",
type: "大雾",
level: "橙色预警",
levelClass: "orange",
district: "涪陵区",
},
{
time: "2025-11-12 09:24:81",
type: "大风",
level: "黄色预警",
levelClass: "yellow",
district: "城口县",
},
]);
//
const filteredData = computed(() => {
const hasFilter =
filters.value.red ||
filters.value.blue ||
filters.value.orange ||
filters.value.yellow;
if (!hasFilter) return warningData.value;
return warningData.value.filter((item) => {
if (filters.value.red && item.levelClass === "red") return true;
if (filters.value.blue && item.levelClass === "blue") return true;
if (filters.value.orange && item.levelClass === "orange") return true;
if (filters.value.yellow && item.levelClass === "yellow") return true;
return false;
});
});
// el-table
const headerCellStyle = () => ({
background: "#17466F",
color: "rgba(255, 255, 255, 0.6)",
fontWeight: "normal",
borderBottom: "1px solid rgba(64, 169, 255, 0.2)",
padding: "5px 20px",
});
const cellStyle = () => ({
background: "#142E49",
color: "rgba(255, 255, 255, 0.9)",
borderBottom: "1px solid rgba(64, 169, 255, 0.1)",
padding: "5px 5px",
});
const rowClassName = ({ rowIndex }) => {
return rowIndex % 2 === 0 ? "even-row" : "odd-row";
};
const emit = defineEmits([
"changeActiveIndex",
"clearMapMarkers",
"hazardItemClick",
"roadItemClick",
]);
// //
const handleClick = (item, index) => { const handleClick = (item, index) => {
// //
if (item.label === "涉灾隐患点") { if (item.label === '涉灾隐患点') {
// //
showHazardPopup.value = !showHazardPopup.value; showHazardPopup.value = !showHazardPopup.value;
if (showHazardPopup.value) { if (showHazardPopup.value) {
@ -350,14 +192,14 @@ const handleClick = (item, index) => {
if (navIconBox) { if (navIconBox) {
const rect = navIconBox.getBoundingClientRect(); const rect = navIconBox.getBoundingClientRect();
popupStyle.value = { popupStyle.value = {
position: "fixed", position: 'fixed',
left: rect.right + 10 + "px", left: rect.right + 10 + 'px',
top: rect.top + "px", top: rect.top + 'px',
zIndex: 2, zIndex: 2,
}; };
} }
} }
} else if (item.label === "路段") { } else if (item.label === '路段') {
// //
// //
@ -372,165 +214,57 @@ const handleClick = (item, index) => {
if (navIconBox) { if (navIconBox) {
const rect = navIconBox.getBoundingClientRect(); const rect = navIconBox.getBoundingClientRect();
roadPopupStyle.value = { roadPopupStyle.value = {
position: "fixed", position: 'fixed',
left: rect.right + 10 + "px", left: rect.right + 10 + 'px',
top: rect.top + "px", top: rect.top + 'px',
zIndex: 3, zIndex: 2,
}; };
} }
} }
emit('showHazardPopupfn', false);
} else { } else {
showHazardPopup.value = false; showHazardPopup.value = false;
showRoadPopup.value = false; showRoadPopup.value = false;
emit('showHazardPopupfn', false);
} }
activeIndex.value = index; activeIndex.value = index;
emit("changeActiveIndex", { emit('changeActiveIndex', {
...item, ...item,
}); });
}; };
// //
const handleHazardItemClick = (item) => { const handleHazardItemClick = item => {
console.log("点击隐患点:", item); console.log('点击隐患点:', item);
emit("hazardItemClick", item); emit('hazardItemClick', item);
// //
// showHazardPopup.value = false; // showHazardPopup.value = false;
emit('showHazardPopupfn', true);
}; };
const roadItem = ref({}); const roadItem = ref({});
// //
const handleRoadItemClick = (item) => { const handleRoadItemClick = item => {
console.log("点击路段:", item); console.log('点击路段:', item);
roadItem.value = item; roadItem.value = item;
emit("roadItemClick", item); emit('roadItemClick', item);
// //
// showRoadPopup.value = false; // showRoadPopup.value = false;
}; };
// //
const clearFilters = () => { const handleClearFilters = () => {
filters.value = { console.log('清除筛选条件');
red: false, //
blue: false,
orange: false,
yellow: false,
};
activeIndex.value = -1; activeIndex.value = -1;
//
showHazardPopup.value = false;
showRoadPopup.value = false;
// //
emit("clearMapMarkers"); emit('clearMapMarkers');
emit('showHazardPopupfn', false);
}; };
//
const tableRef = ref(null);
const isScrolling = ref(true);
const scrollTimer = ref(null);
const scrollSpeed = 50; //
const scrollStep = 1; //
//
const hasFilter = computed(() => {
return (
filters.value.red ||
filters.value.blue ||
filters.value.orange ||
filters.value.yellow
);
});
//
const startAutoScroll = () => {
if (scrollTimer.value) {
clearInterval(scrollTimer.value);
}
if (!isScrolling.value || hasFilter.value) return;
const tableBody = document.querySelector(
".weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap",
);
if (!tableBody) return;
scrollTimer.value = setInterval(() => {
if (tableBody) {
tableBody.scrollTop += scrollStep;
// 使 >=
const maxScroll = tableBody.scrollHeight - tableBody.clientHeight;
if (tableBody.scrollTop >= maxScroll - 2) {
tableBody.scrollTop = 0;
}
}
}, scrollSpeed);
};
//
const stopAutoScroll = () => {
if (scrollTimer.value) {
clearInterval(scrollTimer.value);
scrollTimer.value = null;
}
};
//
const resetScrollToTop = () => {
const tableBody = document.querySelector(
".weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap",
);
if (tableBody) {
tableBody.scrollTop = 0;
}
};
//
const handleMouseEnter = () => {
stopAutoScroll();
};
//
const handleMouseLeave = () => {
if (!hasFilter.value) {
isScrolling.value = true;
startAutoScroll();
}
};
//
watch(hasFilter, (newVal) => {
if (newVal) {
//
stopAutoScroll();
resetScrollToTop();
} else {
//
isScrolling.value = true;
nextTick(() => {
startAutoScroll();
});
}
});
onMounted(() => {
nextTick(() => {
startAutoScroll();
//
const tableContainer = document.querySelector(
".weather-warning-panel .table-container",
);
if (tableContainer) {
tableContainer.addEventListener("mouseenter", handleMouseEnter);
tableContainer.addEventListener("mouseleave", handleMouseLeave);
}
});
});
onUnmounted(() => {
stopAutoScroll();
const tableContainer = document.querySelector(
".weather-warning-panel .table-container",
);
if (tableContainer) {
tableContainer.removeEventListener("mouseenter", handleMouseEnter);
tableContainer.removeEventListener("mouseleave", handleMouseLeave);
}
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -653,27 +387,27 @@ onUnmounted(() => {
// 使 emoji // 使 emoji
&.warning::before { &.warning::before {
content: "📍"; content: '📍';
font-size: vw(24); font-size: vw(24);
} }
&.tunnel::before { &.tunnel::before {
content: "🚇"; content: '🚇';
font-size: vw(24); font-size: vw(24);
} }
&.slope::before { &.slope::before {
content: "⛰️"; content: '⛰️';
font-size: vw(24); font-size: vw(24);
} }
&.bridge::before { &.bridge::before {
content: "🌉"; content: '🌉';
font-size: vw(24); font-size: vw(24);
} }
&.road::before { &.road::before {
content: "🛣️"; content: '🛣️';
font-size: vw(24); font-size: vw(24);
} }
} }
@ -688,198 +422,4 @@ onUnmounted(() => {
} }
} }
} }
//
.weather-warning-wrapper {
display: flex;
flex-direction: column;
justify-content: flex-end;
width: 92%;
height: 50%;
position: absolute;
z-index: 2;
right: 0px;
bottom: 0px;
}
//
.weather-warning-panel {
// border-radius: vw(8);
display: flex;
flex-direction: column;
height: 100%;
.clear-icon {
position: absolute;
top: vw(-50);
right: 0px;
width: vw(40) !important;
height: vw(40) !important;
min-width: vw(28);
min-height: vw(28);
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
background-image: url("../../assets/RiskWarning_img/二级标题栏bg1@2x.png");
background-size: 100% 100%;
background-position: left top;
padding: vw(15);
.header-title {
font-size: vw(18);
font-weight: 500;
color: #fff;
position: relative;
}
.filter-tags {
display: flex;
gap: vw(15);
.tag {
display: flex;
align-items: center;
gap: vw(5);
cursor: pointer;
input {
width: vw(14);
height: vw(14);
min-width: vw(12);
min-height: vw(12);
accent-color: #40a9ff;
}
span {
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
&.tag-red {
color: #ff4d4f;
}
&.tag-blue {
color: #40a9ff;
}
&.tag-orange {
color: #ff7a45;
}
&.tag-yellow {
color: #ffc53d;
}
}
}
}
}
.table-container {
background: rgb(20, 46, 74, 0.95);
flex: 1;
overflow: hidden;
:deep(.el-table__body-wrapper) {
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
}
// el-table
:deep(.el-table) {
background: transparent;
&::before {
display: none;
}
.el-table__inner-wrapper {
background: transparent;
}
.el-table__inner-wrapper:before {
width: 0%;
}
.el-table__header-wrapper {
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 {
background: transparent;
td.el-table__cell {
background: transparent;
font-size: vw(14);
color: rgba(255, 255, 255, 0.9);
padding: vw(5) vw(5);
}
&::-webkit-scrollbar {
display: none !important;
}
}
tr {
background: transparent;
&:hover {
background: rgba(64, 169, 255, 0.05) !important;
}
}
}
.warning-level {
display: flex;
align-items: center;
justify-content: center;
img {
width: vw(15);
height: vw(15);
min-width: vw(10);
min-height: vw(10);
}
// .level-icon {
// width: 0;
// height: 0;
// border-left: 6px solid transparent;
// border-right: 6px solid transparent;
// border-bottom: 10px solid currentColor;
// }
&.red {
color: #ff4d4f;
background: rgba(255, 77, 79, 0.1);
}
&.blue {
color: #40a9ff;
background: rgba(64, 169, 255, 0.1);
}
&.orange {
color: #ff7a45;
background: rgba(255, 122, 69, 0.1);
}
&.yellow {
color: #ffc53d;
background: rgba(255, 197, 61, 0.1);
}
}
}
</style> </style>

View File

@ -0,0 +1,441 @@
<template>
<!-- 气象预警监测表格 -->
<div class="weather-warning-wrapper">
<div class="weather-warning-panel">
<img
class="clear-icon"
src="../../../assets/RiskWarning_img/清除icon@2x.png"
alt=""
@click="clearFilters"
/>
<div class="panel-header">
<div class="header-title">气象预警监测</div>
<div class="filter-tags">
<label class="tag">
<input type="checkbox" v-model="filters.red" />
<span class="">红色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.blue" />
<span class="">蓝色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.orange" />
<span class="">橙色预警</span>
</label>
<label class="tag">
<input type="checkbox" v-model="filters.yellow" />
<span class="">黄色预警</span>
</label>
</div>
</div>
<div class="table-container">
<el-table
v-loading="loading"
element-loading-text="加载中..."
element-loading-background="#1A3E5E"
:data="filteredData"
height="100%"
style="width: 100%; background: transparent"
:header-cell-style="headerCellStyle"
:cell-style="cellStyle"
:row-class-name="rowClassName"
>
<el-table-column prop="time" label="预警时间" min-width="vw(140)" />
<el-table-column prop="type" label="类型" min-width="vw(80)" align="center" />
<el-table-column label="预警等级" min-width="vw(100)" align="center">
<template #default="{ row }">
<div class="warning-level">
<img
:src="
row.levelClass === 'red'
? redIcon
: row.levelClass === 'blue'
? blueIcon
: row.levelClass === 'orange'
? orangeIcon
: yellowIcon
"
alt=""
/>
<span class="ml_10">{{ row.level }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="district" label="预警区县" min-width="vw(80)" />
</el-table>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue';
import { request } from '@/utils/request';
import orangeIcon from '../../../assets/RiskWarning_img/橙色@2x.png';
import yellowIcon from '../../../assets/RiskWarning_img/黄色@2x.png';
import redIcon from '../../../assets/RiskWarning_img//红色@2x.png';
import blueIcon from '../../../assets/RiskWarning_img/蓝色@2x.png';
const emit = defineEmits(['clearFilters']);
//
const filters = ref({
red: false,
blue: false,
orange: false,
yellow: false,
});
//
const warningData = ref([]);
//
const tableRef = ref(null);
const isScrolling = ref(true);
const scrollTimer = ref(null);
const scrollSpeed = 50; //
const scrollStep = 1; //
//
const hasFilter = computed(() => {
return filters.value.red || filters.value.blue || filters.value.orange || filters.value.yellow;
});
//
const startAutoScroll = () => {
if (scrollTimer.value) {
clearInterval(scrollTimer.value);
}
if (!isScrolling.value || hasFilter.value) return;
const tableBody = document.querySelector(
'.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap'
);
if (!tableBody) return;
scrollTimer.value = setInterval(() => {
if (tableBody) {
tableBody.scrollTop += scrollStep;
// 使 >=
const maxScroll = tableBody.scrollHeight - tableBody.clientHeight;
if (tableBody.scrollTop >= maxScroll - 2) {
tableBody.scrollTop = 0;
}
}
}, scrollSpeed);
};
//
const stopAutoScroll = () => {
if (scrollTimer.value) {
clearInterval(scrollTimer.value);
scrollTimer.value = null;
}
};
//
const resetScrollToTop = () => {
const tableBody = document.querySelector(
'.weather-warning-panel .el-table__body-wrapper .el-scrollbar__wrap'
);
if (tableBody) {
tableBody.scrollTop = 0;
}
};
//
const handleMouseEnter = () => {
stopAutoScroll();
};
//
const handleMouseLeave = () => {
if (!hasFilter.value) {
isScrolling.value = true;
startAutoScroll();
}
};
//
watch(hasFilter, newVal => {
if (newVal) {
//
stopAutoScroll();
resetScrollToTop();
} else {
//
isScrolling.value = true;
nextTick(() => {
startAutoScroll();
});
}
});
//
const loading = ref(false);
//
const fetchWeatherWarningData = async () => {
loading.value = true;
try {
const res = await request({
url: '/snow-ops-platform/weather-warning/affected-count/_by_weather',
method: 'GET',
params: {
offset: 0,
limit: 100000,
},
});
console.log('气象预警数据:', res);
if (res.code === '00000' && res.data) {
//
warningData.value = res.data.data.map(item => ({
time: item.startTime || '',
type: item.weatherType || '',
level: item.riskLeve || '',
levelClass: getLevelClass(item.riskLeve || ''),
district: item.countyName || '',
}));
} else {
warningData.value = [];
}
loading.value = false;
nextTick(() => {
startAutoScroll();
//
const tableContainer = document.querySelector('.weather-warning-panel .table-container');
if (tableContainer) {
tableContainer.addEventListener('mouseenter', handleMouseEnter);
tableContainer.addEventListener('mouseleave', handleMouseLeave);
}
});
} catch (error) {
console.error('获取气象预警数据失败:', error);
warningData.value = [];
loading.value = false;
}
};
// class
const getLevelClass = level => {
if (level.includes('红')) return 'red';
if (level.includes('橙')) return 'orange';
if (level.includes('黄')) return 'yellow';
if (level.includes('蓝')) return 'blue';
return '';
};
//
onMounted(() => {
//
console.log('获取气象预警数据');
fetchWeatherWarningData();
});
onUnmounted(() => {
stopAutoScroll();
const tableContainer = document.querySelector('.weather-warning-panel .table-container');
if (tableContainer) {
tableContainer.removeEventListener('mouseenter', handleMouseEnter);
tableContainer.removeEventListener('mouseleave', handleMouseLeave);
}
});
//
const filteredData = computed(() => {
const hasFilter =
filters.value.red || filters.value.blue || filters.value.orange || filters.value.yellow;
if (!hasFilter) return warningData.value;
return warningData.value.filter(item => {
if (filters.value.red && item.levelClass === 'red') return true;
if (filters.value.blue && item.levelClass === 'blue') return true;
if (filters.value.orange && item.levelClass === 'orange') return true;
if (filters.value.yellow && item.levelClass === 'yellow') return true;
return false;
});
});
// el-table
const headerCellStyle = () => ({
background: '#17466F',
color: 'rgba(255, 255, 255, 0.6)',
});
const cellStyle = () => ({
background: '#142E49',
color: 'rgba(255, 255, 255, 0.9)',
borderBottom: '1px solid rgba(64, 169, 255, 0.1)',
padding: '5px 5px',
});
const rowClassName = ({ rowIndex }) => {
return rowIndex % 2 === 0 ? 'even-row' : 'odd-row';
};
//
const clearFilters = () => {
console.log('清除筛选条件');
filters.value = {
red: false,
blue: false,
orange: false,
yellow: false,
};
//
emit('clearFilters');
};
//
const setWarningData = data => {
warningData.value = data;
};
defineExpose({
clearFilters,
setWarningData,
});
</script>
<style lang="scss" scoped>
@function vw($px) {
@return calc($px / 1920 * 100vw);
}
.weather-warning-wrapper {
position: fixed;
bottom: vw(0);
left: 52%;
transform: translateX(-50%);
z-index: 2;
}
.weather-warning-panel {
width: vw(900);
// background: url('../../../assets/RiskWarning_img/@2x.png') no-repeat center center;
// background-size: 100% 100%;
padding: vw(15);
position: relative;
.clear-icon {
position: absolute;
top: vw(-40);
right: vw(15);
width: vw(50);
height: vw(50);
cursor: pointer;
z-index: 10;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
background-image: url('../../../assets/RiskWarning_img/二级标题栏bg1@2x.png');
background-size: 100% 100%;
background-position: left top;
padding: vw(15);
.header-title {
font-size: vw(18);
font-weight: 500;
color: #fff;
}
.filter-tags {
display: flex;
gap: vw(10);
.tag {
display: flex;
align-items: center;
gap: vw(5);
cursor: pointer;
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
input[type='checkbox'] {
width: vw(14);
height: vw(14);
cursor: pointer;
}
}
}
}
.table-container {
height: vw(200);
overflow: hidden;
:deep(.el-table) {
background: transparent;
.el-table__header-wrapper {
th {
background: #17466f;
color: rgba(255, 255, 255, 0.6);
font-weight: normal;
border-bottom: 1px solid rgba(64, 169, 255, 0.2);
}
}
.el-table__body-wrapper {
background: transparent;
tr {
background: transparent;
td {
background: #142e49;
color: rgba(255, 255, 255, 0.9);
border-bottom: 1px solid rgba(64, 169, 255, 0.1);
}
&.even-row {
td {
background: #142e49;
}
}
&.odd-row {
td {
background: #1a3a5c;
}
}
&:hover {
td {
background: rgba(64, 169, 255, 0.2);
}
}
}
}
}
}
}
.warning-level {
display: flex;
align-items: center;
justify-content: center;
gap: vw(5);
img {
width: vw(20);
height: vw(20);
}
}
.ml_10 {
margin-left: vw(10);
}
:deep(.el-table--fit .el-table__inner-wrapper:before) {
width: 0%;
}
:deep(.el-scrollbar__wrap--hidden-default) {
background: #142e49;
}
:deep(.el-table .cell) {
text-align: center;
}
</style>

View File

@ -1,32 +1,74 @@
// 弹窗组件统一数据配置 // 弹窗组件统一数据配置
import { ref } from 'vue';
import { request } from '@/utils/request';
// 行政区域选项 // 行政区域选项
export const regionOptions = [ export const regionOptions = ref([
{ label: "重庆市", value: "重庆市" }, // { label: "重庆市", value: "重庆市" },
{ label: "万州区", value: "万州区" }, // { label: "万州区", value: "万州区" },
{ label: "沙坪坝区", value: "沙坪坝区" }, // { label: "沙坪坝区", value: "沙坪坝区" },
{ label: "渝中区", value: "渝中区" }, // { label: "渝中区", value: "渝中区" },
{ label: "巫溪县", value: "巫溪县" }, // { label: "巫溪县", value: "巫溪县" },
{ label: "涪陵区", value: "涪陵区" }, // { label: "涪陵区", value: "涪陵区" },
{ 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 = [ export const fetchDistrictOptions = async () => {
{ label: "边坡坍塌", value: "边坡坍塌" }, try {
{ label: "路面塌陷", value: "路面塌陷" }, const res = await request({
{ label: "桥梁损坏", value: "桥梁损坏" }, url: '/snow-ops-platform/sm-event/dashboard/district-options',
{ label: "隧道事故", value: "隧道事故" }, method: 'GET',
{ label: "交通主管部门", value: "交通主管部门" }, });
{ label: "公路机构", value: "公路机构" }, if (res && res.code === '00000' && Array.isArray(res.data)) {
{ label: "养护站", value: "养护站" }, // 将接口返回的数据转换为选项格式
{ label: "护路员", value: "护路员" }, const options = res.data.map(item => ({
]; label: item.qxmc,
value: item.xzdm,
}));
// 保留"全部"选项,并添加接口返回的数据
regionOptions.value = [
{ label: "全部", value: "" },
...options,
];
return options;
}
} catch (error) {
console.error('获取行政区域选项失败:', error);
}
return regionOptions.value;
};
// 路况类型选项默认数据会被API数据替换
export const typeOptions = ref([
]);
// 获取路况类型选项
export const fetchRoadConditionOptions = async () => {
try {
const res = await request({
url: '/snow-ops-platform/sm-event/dashboard/road-condition-options',
method: 'GET',
});
if (res && res.code === '00000' && Array.isArray(res.data)) {
// 将接口返回的字符串数组转换为选项格式
const options = res.data.map(item => ({
label: item,
value: item,
}));
typeOptions.value = options;
return options;
}
} catch (error) {
console.error('获取路况类型选项失败:', error);
}
return typeOptions.value;
};
// 管控措施选项 // 管控措施选项
export const controlMeasureOptions = [ export const controlMeasureOptions = [
@ -84,15 +126,9 @@ export const isEndedOptions = [
]; ];
// 行政区域选项(带全部) // 行政区域选项(带全部)
export const regionOptionsWithAll = [ export const regionOptionsWithAll = ref([
{ label: "全部", value: "" }, ]);
{ label: "万州区", value: "wanzhou" },
{ label: "涪陵区", value: "fuling" },
{ label: "合川区", value: "hechuan" },
{ label: "万盛区", value: "wansheng" },
{ label: "长寿区", value: "changshou" },
{ label: "城口区", value: "chengkou" },
];
// 格式化日期时间为接口所需格式 // 格式化日期时间为接口所需格式
export const formatDateTime = (date) => { export const formatDateTime = (date) => {
@ -120,4 +156,6 @@ export default {
isEndedOptions, isEndedOptions,
regionOptionsWithAll, regionOptionsWithAll,
formatDateTime, formatDateTime,
}; fetchRoadConditionOptions,
fetchDistrictOptions,
};

View File

@ -1,17 +1,9 @@
<template> <template>
<div class="main"> <div class="main">
<div class="top_title"> <div class="top_title">
<img <img class="title_bg" src="../../assets/RiskWarning_img/一级标题栏bg@2x.png" alt="" />
class="title_bg"
src="../../assets/RiskWarning_img/一级标题栏bg@2x.png"
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"
@ -43,7 +35,7 @@
@openWarningSituation="openDialog('warningSituation')" @openWarningSituation="openDialog('warningSituation')"
@openResponseStatus="openDialog('responseStatus')" @openResponseStatus="openDialog('responseStatus')"
@openDispatchDistrict="openDialog('dispatchDistrict')" @openDispatchDistrict="openDialog('dispatchDistrict')"
@showCenterCard="(item) => handleCenterCardClick(item)" @showCenterCard="item => handleCenterCardClick(item)"
></left> ></left>
</div> </div>
<div class="right"> <div class="right">
@ -64,21 +56,31 @@
:dateRange="getdateRange" :dateRange="getdateRange"
:roadItem="roadItem" :roadItem="roadItem"
@districtClick="handleDistrictClick" @districtClick="handleDistrictClick"
@riskPointStatsChange="handleRiskPointStatsChange"
@update:roadvalArr="updateRoadvalArr"
@openHazardPointSituation="handleOpenHazardPointSituation"
/> />
</div> </div>
<!-- 地图遮罩层 --> <!-- 地图遮罩层 -->
<div class="map-mask" aria-hidden="true"></div> <div class="map-mask" aria-hidden="true"></div>
</div> </div>
<div class="bottom"> <div class="bottom">
<bottom <bottom
@roadItemClick="roadItemClick" @roadItemClick="roadItemClick"
@changeActiveIndex="changeActiveIndex" @changeActiveIndex="changeActiveIndex"
@hazardItemClick="handleHazardItemClick"
@clearMapMarkers="clearMapMarkers" @clearMapMarkers="clearMapMarkers"
@showHazardPopupfn="showHazardPopupfn"
></bottom> ></bottom>
</div> </div>
<top <top
class="top" class="top"
:roadItem="roadItem"
:showHazardPopup="showHazardPopup"
:riskPointStats="riskPointStats"
:roadvalArrtrue="roadvalArrtrue"
@openAIResult="openDialog('aiWarningResult')" @openAIResult="openDialog('aiWarningResult')"
@dateRangeChange="handleDateRangeChange" @dateRangeChange="handleDateRangeChange"
></top> ></top>
@ -164,6 +166,8 @@
<!-- 潼南基本信息对话框 --> <!-- 潼南基本信息对话框 -->
<tongnanInfoDialog <tongnanInfoDialog
v-model:visible="dialogVisible.tongnanInfo" v-model:visible="dialogVisible.tongnanInfo"
:allCountyData="allCountyData"
:tongnanInfoItemData="tongnanInfoItemData"
@close="closeDialog('tongnanInfo')" @close="closeDialog('tongnanInfo')"
@call="openDialog('confirm')" @call="openDialog('confirm')"
/> />
@ -173,7 +177,13 @@
v-model:visible="dialogVisible.tongnanResponsible" v-model:visible="dialogVisible.tongnanResponsible"
:allCountyData="allCountyData" :allCountyData="allCountyData"
@close="closeDialog('tongnanResponsible')" @close="closeDialog('tongnanResponsible')"
@detail="openDialog('tongnanInfo')" @detail="openDialog('tongnanProjectPerson')"
/>
<!-- 项目负责人对话框 -->
<tongnanProjectPersonDialog
v-model:visible="dialogVisible.tongnanProjectPerson"
:allCountyData="allCountyData"
@close="closeDialog('tongnanProjectPerson')"
/> />
<!-- 抢通情况对话框 --> <!-- 抢通情况对话框 -->
@ -208,6 +218,7 @@
:allCountyData="allCountyData" :allCountyData="allCountyData"
@close="closeDialog('tongnanTeam')" @close="closeDialog('tongnanTeam')"
@view="openDialog('tongnanInfo')" @view="openDialog('tongnanInfo')"
@itemdata="tongnanInfoItemDatafn()"
/> />
<!-- 预警情况对话框 --> <!-- 预警情况对话框 -->
@ -224,45 +235,54 @@
v-model:visible="dialogVisible.tunnelInfo" v-model:visible="dialogVisible.tunnelInfo"
@close="closeDialog('tunnelInfo')" @close="closeDialog('tunnelInfo')"
/> />
<hazardPointSituationDialog
v-model:visible="dialogVisible.hazardPointSituation"
:data="hazardPointData"
@close="closeDialog('hazardPointSituation')"
/>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted, provide } from "vue"; import { ref, onMounted, provide } 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';
import top from "./top.vue"; import top from './top.vue';
import ChongqingMap from "./component/ChongqingMap.vue"; import ChongqingMap from './component/ChongqingMap.vue';
import { fetchRoadConditionOptions, fetchDistrictOptions } from './component/index.js';
// //
import responseSituationDiaLog from "./Dialog/responseSituationDiaLog.vue"; import responseSituationDiaLog from './Dialog/responseSituationDiaLog.vue';
import warningInfoDialog from "./Dialog/warningInfoDialog.vue"; import warningInfoDialog from './Dialog/warningInfoDialog.vue';
import eventDetailDialog from "./Dialog/eventDetailDialog.vue"; import eventDetailDialog from './Dialog/eventDetailDialog.vue';
import confirmDialog from "./Dialog/confirmDialog.vue"; import confirmDialog from './Dialog/confirmDialog.vue';
import riskPointDetailDialog from "./Dialog/riskPointDetailDialog.vue"; import riskPointDetailDialog from './Dialog/riskPointDetailDialog.vue';
import impactPointDialog from "./Dialog/impactPointDialog.vue"; import impactPointDialog from './Dialog/impactPointDialog.vue';
import impactPointDetailDialog from "./Dialog/impactPointDetailDialog.vue"; import impactPointDetailDialog from './Dialog/impactPointDetailDialog.vue';
import responsePointDetailDialog from "./Dialog/responsePointDetailDialog.vue"; import responsePointDetailDialog from './Dialog/responsePointDetailDialog.vue';
import responsePointInfoDialog from "./Dialog/responsePointInfoDialog.vue"; import responsePointInfoDialog from './Dialog/responsePointInfoDialog.vue';
import responseStatusDialog from "./Dialog/responseStatusDialog.vue"; import responseStatusDialog from './Dialog/responseStatusDialog.vue';
import aiWarningResultDialog from "./Dialog/aiWarningResultDialog.vue"; import aiWarningResultDialog from './Dialog/aiWarningResultDialog.vue';
import tongnanInfoDialog from "./Dialog/tongnanInfoDialog.vue"; import tongnanInfoDialog from './Dialog/tongnanInfoDialog.vue';
import tongnanResponsibleDialog from "./Dialog/tongnanResponsibleDialog.vue"; import tongnanResponsibleDialog from './Dialog/tongnanResponsibleDialog.vue';
import clearanceSituationDialog from "./Dialog/clearanceSituationDialog.vue"; import clearanceSituationDialog from './Dialog/clearanceSituationDialog.vue';
import controlSituationDialog from "./Dialog/controlSituationDialog.vue"; import controlSituationDialog from './Dialog/controlSituationDialog.vue';
import dispatchDetailDialog from "./Dialog/dispatchDetailDialog.vue"; import dispatchDetailDialog from './Dialog/dispatchDetailDialog.vue';
import dispatchDistrictDialog from "./Dialog/dispatchDistrictDialog.vue"; import dispatchDistrictDialog from './Dialog/dispatchDistrictDialog.vue';
import tongnanTeamDialog from "./Dialog/tongnanTeamDialog.vue"; import tongnanTeamDialog from './Dialog/tongnanTeamDialog.vue';
import warningSituationDialog from "./Dialog/warningSituationDialog.vue"; import warningSituationDialog from './Dialog/warningSituationDialog.vue';
import tunnelInfoDialog from "./Dialog/tunnelInfoDialog.vue"; import tunnelInfoDialog from './Dialog/tunnelInfoDialog.vue';
import centerInfoCard from "./Dialog/centerInfoCard.vue"; import centerInfoCard from './Dialog/centerInfoCard.vue';
import tongnanProjectPersonDialog from './Dialog/tongnanProjectPersonDialog.vue';
import hazardPointSituationDialog from './Dialog/hazardPointSituationDialog.vue';
import "./component/el-select.scss"; import './component/el-select.scss';
import "./component/date-picker-theme.scss"; import './component/date-picker-theme.scss';
// //
const dialogVisible = ref({ const dialogVisible = ref({
@ -286,15 +306,31 @@ const dialogVisible = ref({
tongnanTeam: false, tongnanTeam: false,
warningSituation: false, warningSituation: false,
tunnelInfo: false, tunnelInfo: false,
tongnanProjectPerson: false,
hazardPointSituation: false,
}); });
const activeitem = ref({}); const activeitem = ref({});
//
const riskPointStats = ref({
重大路外隐患点: 0,
重大路内隐患点: 0,
较大路外隐患点: 0,
较大路内隐患点: 0,
一般路内隐患点: 0,
一般路外隐患点: 0,
风险点总数: 0,
});
//
const hazardPointData = ref({});
// //
const getdateRange = ref([]); const getdateRange = ref([]);
// //
const handleDateRangeChange = (val) => { const handleDateRangeChange = val => {
console.log("日期范围变化:", val); console.log('日期范围变化:', val);
getdateRange.value = val; getdateRange.value = val;
}; };
@ -302,27 +338,59 @@ const handleDateRangeChange = (val) => {
const chongqingMapRef = ref(null); const chongqingMapRef = ref(null);
// //
const changeActiveIndex = (index) => { const changeActiveIndex = index => {
activeitem.value = index; activeitem.value = index;
}; };
const roadItem = ref({}); const roadItem = ref({});
const roadItemClick = (item) => { const roadItemClick = item => {
console.log("点击路段:", item); console.log('点击路段:', item);
roadItem.value = item; roadItem.value = item;
}; };
//
const handleHazardItemClick = item => {
console.log('点击隐患点:', item);
//
if (chongqingMapRef.value) {
chongqingMapRef.value.handleHazardItemClick(item);
}
};
const showHazardPopup = ref(false);
const showHazardPopupfn = val => {
showHazardPopup.value = val;
};
//
const handleRiskPointStatsChange = stats => {
console.log('风险点统计数据变化:', stats);
riskPointStats.value = stats;
};
//
const roadvalArrtrue = ref([]);
const updateRoadvalArr = roadvalArr => {
roadvalArrtrue.value = roadvalArr;
// let num = 0;
// roadvalArrtrue.value.forEach(item => {
// num += item.value;
// });
// roadvalArrtrue.value.push({ label: '', value: num });
console.log('更新路段统计数据:', roadvalArr);
console.log('更新路段统计数据:', roadvalArrtrue);
};
// //
const openResourceDetail = (item) => { const openResourceDetail = item => {
console.log("打开资源详情:", item); console.log('打开资源详情:', item);
// //
if (item.label === "全市普通公路抢险队伍" || item.label === "人员") { if (item.label === '全市普通公路抢险队伍' || item.label === '人员') {
// //
if (chongqingMapRef.value) { if (chongqingMapRef.value) {
chongqingMapRef.value.getEmergencyForceData(); chongqingMapRef.value.getEmergencyForceData();
} }
} }
// //
const key = item.label.toLowerCase().replace(/[^a-z]/g, ""); const key = item.label.toLowerCase().replace(/[^a-z]/g, '');
if (dialogVisible.value[key] !== undefined) { if (dialogVisible.value[key] !== undefined) {
dialogVisible.value[key] = true; dialogVisible.value[key] = true;
} }
@ -330,51 +398,73 @@ const openResourceDetail = (item) => {
// //
const clearMapMarkers = () => { const clearMapMarkers = () => {
console.log("清除地图标记"); console.log('清除地图标记');
if (chongqingMapRef.value) { if (chongqingMapRef.value) {
chongqingMapRef.value.clearProjectMarkers(); chongqingMapRef.value.clearProjectMarkers();
} }
}; };
//
const handleClearFilters = () => {
console.log('index.vue 处理清除筛选事件');
//
clearMapMarkers();
//
activeitem.value = {};
roadItem.value = {};
showHazardPopup.value = false;
};
// //
const openDialog = (dialogName) => { const openDialog = dialogName => {
dialogVisible.value[dialogName] = true; dialogVisible.value[dialogName] = true;
}; };
const impactPointDetailItem = ref({}); const impactPointDetailItem = ref({});
// //
const handleImpactPointClick = (item) => { const handleImpactPointClick = item => {
console.log("影响点点击:", item); console.log('影响点点击:', item);
impactPointDetailItem.value = item; impactPointDetailItem.value = item;
}; };
const handleImpactItem = ref({}); const handleImpactItem = ref({});
const handleImpactClickItem = (item) => { const handleImpactClickItem = item => {
console.log("影响点点击详情:", item); console.log('影响点点击详情:', item);
handleImpactItem.value = item; handleImpactItem.value = item;
}; };
const tongnanInfoItemData = ref({});
const tongnanInfoItemDatafn = item => {
console.log('点击详情:', item);
tongnanInfoItemData.value = item;
};
// //
const closeDialog = (dialogName) => { const closeDialog = dialogName => {
// //
console.log("关闭弹窗", dialogName); console.log('关闭弹窗', dialogName);
dialogVisible.value[dialogName] = false; dialogVisible.value[dialogName] = false;
}; };
//
const handleOpenHazardPointSituation = item => {
console.log('打开涉灾隐患点情况弹窗:', item);
hazardPointData.value = item;
dialogVisible.value.hazardPointSituation = true;
};
// //
const warningitem = ref({}); const warningitem = ref({});
const handleWarningClick = (item) => { const handleWarningClick = item => {
console.log("气象预警点击:", item); console.log('气象预警点击:', item);
warningitem.value = item; warningitem.value = item;
}; };
// //
const confirmConfig = ref({ const confirmConfig = ref({
title: "提示", title: '提示',
message: "是否拨打电话?", message: '是否拨打电话?',
confirmText: "确定", confirmText: '确定',
cancelText: "取消", cancelText: '取消',
}); });
// //
const openConfirm = (config) => { const openConfirm = config => {
confirmConfig.value = { ...confirmConfig.value, ...config }; confirmConfig.value = { ...confirmConfig.value, ...config };
dialogVisible.value.confirm = true; dialogVisible.value.confirm = true;
}; };
@ -382,23 +472,23 @@ const openConfirm = (config) => {
const showCenterCard = ref(false); const showCenterCard = ref(false);
const allCountyData = ref({}); const allCountyData = ref({});
// //
const handleDistrictClick = (item) => { const handleDistrictClick = item => {
console.log("区县点击:", item); console.log('区县点击:', item);
allCountyData.value = item; allCountyData.value = item;
if (item.data.roadType == "national") { if (item.data.roadType == 'national') {
// //
openDialog("tongnanTeam"); openDialog('tongnanTeam');
} else if (item.data.roadType == "rural") { } else if (item.data.roadType == 'rural') {
openDialog("responseSituation"); openDialog('responseSituation');
} else if (item.data.type == "project" && item.data.roadType == "-") { } else if (item.data.type == 'project' && item.data.roadType == '-') {
// //
openDialog("tongnanResponsible"); openDialog('tongnanResponsible');
} }
}; };
// //
const handleCenterCardClick = (item) => { const handleCenterCardClick = item => {
console.log("中心卡片点击:", item); console.log('中心卡片点击:', item);
// //
if (chongqingMapRef.value && item.data) { if (chongqingMapRef.value && item.data) {
@ -409,10 +499,7 @@ const handleCenterCardClick = (item) => {
chongqingMapRef.value.openCenterCard(cardData); chongqingMapRef.value.openCenterCard(cardData);
// //
if ( if (item.data.length > 0 && (item.data[0].countyName || item.data[0].name)) {
item.data.length > 0 &&
(item.data[0].countyName || item.data[0].name)
) {
const firstCounty = item.data[0].countyName || item.data[0].name; const firstCounty = item.data[0].countyName || item.data[0].name;
chongqingMapRef.value.locateToDistrict(firstCounty); chongqingMapRef.value.locateToDistrict(firstCounty);
} }
@ -420,15 +507,15 @@ const handleCenterCardClick = (item) => {
}; };
// //
const getCardTitleByType = (type) => { const getCardTitleByType = type => {
const titleMap = { const titleMap = {
first: "国省道调度", first: '国省道调度',
second: "农村公路调度", second: '农村公路调度',
third: "建设工程调度", third: '建设工程调度',
}; };
return titleMap[type] || "调度统计"; return titleMap[type] || '调度统计';
}; };
const handleCenterCardClickType = (item) => { const handleCenterCardClickType = item => {
console.log(item.data); console.log(item.data);
showCenterCard.value = true; showCenterCard.value = true;
// if (item.type === "second") { // if (item.type === "second") {
@ -445,12 +532,12 @@ const refreshLeftData = ref(null);
const refreshRightData = ref(null); const refreshRightData = ref(null);
// //
const setRefreshLeftData = (callback) => { const setRefreshLeftData = callback => {
refreshLeftData.value = callback; refreshLeftData.value = callback;
}; };
// right.vue // right.vue
const setRefreshRightData = (callback) => { const setRefreshRightData = callback => {
refreshRightData.value = callback; refreshRightData.value = callback;
}; };
@ -466,10 +553,10 @@ const triggerRefreshLeftData = () => {
}; };
// //
provide("setRefreshLeftData", setRefreshLeftData); provide('setRefreshLeftData', setRefreshLeftData);
provide("triggerRefreshLeftData", triggerRefreshLeftData); provide('triggerRefreshLeftData', triggerRefreshLeftData);
provide("setRefreshRightData", setRefreshRightData); provide('setRefreshRightData', setRefreshRightData);
provide("getdateRange", getdateRange); provide('getdateRange', getdateRange);
// ==================== ==================== // ==================== ====================
@ -488,6 +575,8 @@ const mapBase = useMapBase(mapStore);
onMounted(() => { onMounted(() => {
// //
mapBase.loadBaseData(); mapBase.loadBaseData();
fetchRoadConditionOptions(); //
fetchDistrictOptions(); //
}); });
</script> </script>
@ -502,7 +591,7 @@ onMounted(() => {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url("../../assets/RiskWarning_img/遮罩层.png"); background-image: url('../../assets/RiskWarning_img/遮罩层.png');
background-size: cover; background-size: cover;
background-position: center; background-position: center;
} }
@ -571,9 +660,17 @@ onMounted(() => {
position: absolute; position: absolute;
bottom: 5px; bottom: 5px;
left: 25%; left: 25%;
width: 50%; width: 20%;
height: 43%; height: 43%;
} }
.weather-warning-table {
position: absolute;
bottom: 5px;
left: 30%;
width: 40%;
height: 43%;
// z-index: 1;
}
.top { .top {
position: absolute; position: absolute;
@ -591,7 +688,7 @@ onMounted(() => {
// left: 25%; // left: 25%;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 2; // z-index: 2;
} }
/* 地图底层 - 填满整个容器 */ /* 地图底层 - 填满整个容器 */
@ -609,8 +706,7 @@ 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;
} }
// //

View File

@ -19,7 +19,8 @@
<div class="resource-info"> <div class="resource-info">
<div class="resource-label">{{ item.label }}</div> <div class="resource-label">{{ item.label }}</div>
<div class="resource-value"> <div class="resource-value">
{{ item.value }}<span class="unit">{{ item.unit }}</span> {{ item.value }}
<span class="unit">{{ item.unit }}</span>
</div> </div>
</div> </div>
</div> </div>
@ -28,8 +29,8 @@
<!-- 管控路段数 --> <!-- 管控路段数 -->
<div class="control-section"> <div class="control-section">
<div class="control-title display jc_sb ai_center"> <div class="control-title display jc_sb ai_center">
<div class="f1">管控路段数 <span class="control-num">2</span></div> <div class="f1">管控路段数</div>
<div class="f1">管控项目 <span class="control-num">2</span></div> <div class="f1">管控项目</div>
</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">
@ -78,11 +79,7 @@
</div> </div>
</div> </div>
<div class="patrol-grid"> <div class="patrol-grid">
<div <div v-for="(item, index) in patrolData" :key="index" class="patrol-item">
v-for="(item, index) in patrolData"
:key="index"
class="patrol-item"
>
<div class="patrol-value">{{ item.value }}</div> <div class="patrol-value">{{ item.value }}</div>
<div class="patrol-label">{{ item.label }}</div> <div class="patrol-label">{{ item.label }}</div>
</div> </div>
@ -93,16 +90,13 @@
<div class="rescue-section"> <div class="rescue-section">
<div class="rescue-title">抢险投入情况</div> <div class="rescue-title">抢险投入情况</div>
<div class="rescue-grid"> <div class="rescue-grid">
<div <div v-for="(item, index) in rescueData" :key="index" class="rescue-item">
v-for="(item, index) in rescueData"
:key="index"
class="rescue-item"
>
<!-- <div class="rescue-icon" :class="item.iconClass"></div> --> <!-- <div class="rescue-icon" :class="item.iconClass"></div> -->
<img class="rescue-icon" :src="item.img" alt="" /> <img class="rescue-icon" :src="item.img" alt="" />
<div class="rescue-info"> <div class="rescue-info">
<div class="rescue-value"> <div class="rescue-value">
{{ item.value }}<span class="unit">{{ item.unit }}</span> {{ item.value }}
<span class="unit">{{ item.unit }}</span>
</div> </div>
<div class="rescue-label">{{ item.label }}</div> <div class="rescue-label">{{ item.label }}</div>
</div> </div>
@ -116,9 +110,7 @@
<SectionHeader title="受灾情况"> <SectionHeader title="受灾情况">
<template #right> <template #right>
<div class="header-filters"> <div class="header-filters">
<span class="filter-item active" @click="handleDateRangeClick()" <span class="filter-item active" @click="handleDateRangeClick()">本轮</span>
>本轮</span
>
<div class="date-range-wrapper"> <div class="date-range-wrapper">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
@ -180,7 +172,8 @@
:class="item.class" :class="item.class"
> >
<div class="damage-value"> <div class="damage-value">
{{ item.value }}<span class="unit">{{ item.unit }}</span> {{ item.value }}
<span class="unit">{{ item.unit }}</span>
</div> </div>
<div class="damage-label">{{ item.label }}</div> <div class="damage-label">{{ item.label }}</div>
</div> </div>
@ -197,46 +190,42 @@
</template> </template>
<script setup> <script setup>
import { ref, computed, onMounted, inject, watch } from "vue"; import { ref, computed, onMounted, inject, watch } from 'vue';
import { request } from "@/utils/request"; import { request } from '@/utils/request';
import SectionHeader from "./component/sectionHeader.vue"; import SectionHeader from './component/sectionHeader.vue';
import { Calendar } from "@element-plus/icons-vue"; import { Calendar } from '@element-plus/icons-vue';
import icon1 from "../../assets/RiskWarning_img/icon1@2x.png"; import icon1 from '../../assets/RiskWarning_img/icon1@2x.png';
import icon2 from "../../assets/RiskWarning_img/icon2@2x.png"; import icon2 from '../../assets/RiskWarning_img/icon2@2x.png';
import icon3 from "../../assets/RiskWarning_img/icon3@2x.png"; 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-2@2x.png';
import icon13 from "../../assets/RiskWarning_img/icon-3@2x.png"; import icon13 from '../../assets/RiskWarning_img/icon-3@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';
import icon55 from "../../assets/RiskWarning_img/路径55@2x.png"; import icon55 from '../../assets/RiskWarning_img/路径55@2x.png';
import icon62 from "../../assets/RiskWarning_img/路径62@2x.png"; import icon62 from '../../assets/RiskWarning_img/路径62@2x.png';
import icon621 from "../../assets/RiskWarning_img/路径62@2x (1).png"; import icon621 from '../../assets/RiskWarning_img/路径62@2x (1).png';
import icon622 from "../../assets/RiskWarning_img/路径62@2x (2).png"; import icon622 from '../../assets/RiskWarning_img/路径62@2x (2).png';
const emit = defineEmits([ const emit = defineEmits(['openClearanceSituation', 'openControlSituation', 'openResourceDetail']);
"openClearanceSituation",
"openControlSituation",
"openResourceDetail",
]);
// //
const setRefreshRightData = inject("setRefreshRightData"); const setRefreshRightData = inject('setRefreshRightData');
const getdateRange = inject("getdateRange", ref([])); const getdateRange = inject('getdateRange', ref([]));
// //
const handleDateChange = (val) => { const handleDateChange = val => {
dateRange.value = val; dateRange.value = val;
getDisasterStats(); getDisasterStats();
}; };
// //
const handleDateRangeClick = (val) => { const handleDateRangeClick = val => {
dateRange.value = []; dateRange.value = [];
getDisasterStats(); getDisasterStats();
}; };
@ -245,8 +234,8 @@ const handleDateRangeClick = (val) => {
const getYhYjllList = async () => { const getYhYjllList = async () => {
try { try {
const res = await request({ const res = await request({
url: "/snow-ops-platform/yhYjll/list", url: '/snow-ops-platform/yhYjll/list',
method: "GET", method: 'GET',
params: { params: {
// longitude: 114.305556, // longitude: 114.305556,
// latitude: 22.624722, // latitude: 22.624722,
@ -254,10 +243,10 @@ const getYhYjllList = async () => {
}, },
}); });
console.log(res); console.log(res);
if (res.code == "00000") { if (res.code == '00000') {
let gl1Rysls = 0; // let gl1Rysls = 0; //
let gl1Yjllmcs = 0; // let gl1Yjllmcs = 0; //
res.data.forEach((item) => { res.data.forEach(item => {
if (item.gl1Lx == 1 || item.gl1Lx == 2) { if (item.gl1Lx == 1 || item.gl1Lx == 2) {
gl1Yjllmcs = gl1Yjllmcs + 1; gl1Yjllmcs = gl1Yjllmcs + 1;
} }
@ -265,20 +254,20 @@ const getYhYjllList = async () => {
}); });
if (gl1Rysls > 10000) { if (gl1Rysls > 10000) {
gl1Rysls = (gl1Rysls / 10000).toFixed(2); gl1Rysls = (gl1Rysls / 10000).toFixed(2);
resourceData.value[1].unit = "万人"; resourceData.value[1].unit = '万人';
} else { } else {
resourceData.value[1].value = gl1Rysls; resourceData.value[1].value = gl1Rysls;
resourceData.value[1].unit = "人"; resourceData.value[1].unit = '人';
} }
resourceData.value[0].value = gl1Yjllmcs; resourceData.value[0].value = gl1Yjllmcs;
} }
} catch (error) { } catch (error) {
console.error("获取应急力量列表失败:", error); console.error('获取应急力量列表失败:', error);
} }
}; };
// //
const getIconByType = (type) => { const getIconByType = type => {
const iconMap = { const iconMap = {
1: icon1, // 1: icon1, //
2: icon2, // 2: icon2, //
@ -292,16 +281,16 @@ const getIconByType = (type) => {
const getYhYjllListMaterials = async () => { const getYhYjllListMaterials = async () => {
try { try {
const res = await request({ const res = await request({
url: "/snow-ops-platform/yhYjll/listMaterials", url: '/snow-ops-platform/yhYjll/listMaterials',
method: "GET", method: 'GET',
params: {}, params: {},
}); });
console.log("物资列表:", res); console.log('物资列表:', res);
if (res.code == "00000" && res.data) { if (res.code == '00000' && res.data) {
let equipment = 0; // let equipment = 0; //
let materials = 0; // let materials = 0; //
res.data.forEach((item) => { res.data.forEach(item => {
if (item.gl1Wzlx == 1) { if (item.gl1Wzlx == 1) {
equipment = equipment + extractAndSumNumbers(item.gl1Wzsl); equipment = equipment + extractAndSumNumbers(item.gl1Wzsl);
} else if (item.gl1Wzlx == 2) { } else if (item.gl1Wzlx == 2) {
@ -310,18 +299,18 @@ const getYhYjllListMaterials = async () => {
}); });
if (materials > 10000) { if (materials > 10000) {
resourceData.value[3].value = (materials / 10000).toFixed(2); resourceData.value[3].value = (materials / 10000).toFixed(2);
resourceData.value[3].unit = "万件"; resourceData.value[3].unit = '万件';
} else { } else {
resourceData.value[3].value = materials; resourceData.value[3].value = materials;
resourceData.value[3].unit = "件"; resourceData.value[3].unit = '件';
} }
console.log(equipment, materials); console.log(equipment, materials);
// //
resourceData.value[2].value = equipment || "0"; resourceData.value[2].value = equipment || '0';
} }
} catch (error) { } catch (error) {
console.error("获取物资列表失败:", error); console.error('获取物资列表失败:', error);
} }
}; };
@ -329,27 +318,27 @@ const getYhYjllListMaterials = async () => {
const getControlStats = async () => { const getControlStats = async () => {
try { try {
const res = await request({ const res = await request({
url: "/snow-ops-platform/sm-event/dashboard/control-stats", url: '/snow-ops-platform/sm-event/dashboard/control-stats',
method: "GET", method: 'GET',
}); });
console.log("管控统计数据:", res); console.log('管控统计数据:', res);
if (res.code == "00000" && res.data) { if (res.code == '00000' && res.data) {
const data = res.data; const data = res.data;
// controlData1value // controlData1value
controlData1.value.forEach((item) => { controlData1.value.forEach(item => {
if (item.label === "封闭管控数") { if (item.label === '封闭管控数') {
item.value = data.fullClosureCount || "0"; item.value = data.fullClosureCount || '0';
} else if (item.label === "半幅通行数") { } else if (item.label === '半幅通行数') {
item.value = data.halfClosureCount || "0"; item.value = data.halfClosureCount || '0';
} else if (item.label === "限速(限车型)数") { } else if (item.label === '限速(限车型)数') {
item.value = data.speedLimitCount || "0"; item.value = data.speedLimitCount || '0';
} else if (item.label === "告警阻拦处数") { } else if (item.label === '告警阻拦处数') {
item.value = data.warningBlockCount || "0"; item.value = data.warningBlockCount || '0';
} }
}); });
} }
} catch (error) { } catch (error) {
console.error("获取管控统计数据失败:", error); console.error('获取管控统计数据失败:', error);
} }
}; };
@ -357,41 +346,41 @@ const getControlStats = async () => {
const getRescueInputStats = async () => { const getRescueInputStats = async () => {
try { try {
const res = await request({ const res = await request({
url: "/snow-ops-platform/sm-event/dashboard/rescue-input-stats", url: '/snow-ops-platform/sm-event/dashboard/rescue-input-stats',
method: "GET", method: 'GET',
}); });
console.log("抢险投入统计数据:", res); console.log('抢险投入统计数据:', res);
if (res.code == "00000" && res.data) { if (res.code == '00000' && res.data) {
const data = res.data; const data = res.data;
// rescueDatavalue // rescueDatavalue
rescueData.value.forEach((item) => { rescueData.value.forEach(item => {
if (item.label === "本轮出动人次") { if (item.label === '本轮出动人次') {
item.value = data.investedManpower || "0"; item.value = data.investedManpower || '0';
item.unit = "人"; item.unit = '人';
if (item.value > 10000) { if (item.value > 10000) {
item.value = (item.value / 10000).toFixed(2); item.value = (item.value / 10000).toFixed(2);
item.unit = "万人"; item.unit = '万人';
} }
} else if (item.label === "本轮出动设备") { } else if (item.label === '本轮出动设备') {
item.value = data.investedMachinery || "0"; item.value = data.investedMachinery || '0';
item.unit = "台"; item.unit = '台';
if (item.value > 10000) { if (item.value > 10000) {
item.value = (item.value / 10000).toFixed(2); item.value = (item.value / 10000).toFixed(2);
item.unit = "万台"; item.unit = '万台';
} }
} else if (item.label === "清理塌方") { } else if (item.label === '清理塌方') {
// //
item.value = data.clearedLandslide.toFixed(2) || 0; item.value = data.clearedLandslide.toFixed(2) || 0;
item.unit = "立方米"; item.unit = '立方米';
if (item.value > 10000) { if (item.value > 10000) {
item.value = (item.value / 10000).toFixed(2); item.value = (item.value / 10000).toFixed(2);
item.unit = "万立方米"; item.unit = '万立方米';
} }
} }
}); });
} }
} catch (error) { } catch (error) {
console.error("获取抢险投入统计数据失败:", error); console.error('获取抢险投入统计数据失败:', error);
} }
}; };
@ -399,102 +388,98 @@ const getRescueInputStats = async () => {
const getDisasterStats = async () => { const getDisasterStats = async () => {
try { try {
const res = await request({ const res = await request({
url: "/snow-ops-platform/sm-event/dashboard/disaster-stats", url: '/snow-ops-platform/sm-event/dashboard/disaster-stats',
method: "GET", method: 'GET',
}); });
console.log("灾害统计数据:", res); console.log('灾害统计数据:', res);
if (res.code == "00000" && res.data) { if (res.code == '00000' && res.data) {
const data = res.data; const data = res.data;
// blockDatavalue // blockDatavalue
blockData.value.forEach((item) => { blockData.value.forEach(item => {
if (item.label === "今日新增阻断数") { if (item.label === '今日新增阻断数') {
item.current = data.todayNormalCount || "0"; item.current = data.todayNormalCount || '0';
item.total = data.todayTotalCount || "0"; item.total = data.todayTotalCount || '0';
} else if (item.label === "本轮累计阻断数") { } else if (item.label === '本轮累计阻断数') {
item.current = data.roundNormalCount || "0"; item.current = data.roundNormalCount || '0';
item.total = data.roundTotalCount || "0"; item.total = data.roundTotalCount || '0';
} }
}); });
// deathDatavalue // deathDatavalue
deathData.value.value = data.roundDeadCount || "0"; deathData.value.value = data.roundDeadCount || '0';
// damageDatavalue // damageDatavalue
damageData.value.forEach((item) => { damageData.value.forEach(item => {
if (item.label === "本轮塌方量") { if (item.label === '本轮塌方量') {
data.roundLandslideVolume = data.roundLandslideVolume.toFixed(2); data.roundLandslideVolume = data.roundLandslideVolume.toFixed(2);
if (data.roundLandslideVolume > 10000) { if (data.roundLandslideVolume > 10000) {
item.value = (data.roundLandslideVolume / 10000).toFixed(2) || "0"; item.value = (data.roundLandslideVolume / 10000).toFixed(2) || '0';
item.unit = "万立方米"; item.unit = '万立方米';
} else { } else {
item.value = data.roundLandslideVolume || "0"; item.value = data.roundLandslideVolume || '0';
item.unit = "立方米"; item.unit = '立方米';
} }
} else if (item.label === "汛期塌方量") { } else if (item.label === '汛期塌方量') {
data.floodSeasonLandslideVolume = data.floodSeasonLandslideVolume = data.floodSeasonLandslideVolume.toFixed(2);
data.floodSeasonLandslideVolume.toFixed(2);
if (data.floodSeasonLandslideVolume > 10000) { if (data.floodSeasonLandslideVolume > 10000) {
item.value = item.value = (data.floodSeasonLandslideVolume / 10000).toFixed(2) || '0';
(data.floodSeasonLandslideVolume / 10000).toFixed(2) || "0"; item.unit = '万立方米';
item.unit = "万立方米";
} else { } else {
item.value = data.floodSeasonLandslideVolume || "0"; item.value = data.floodSeasonLandslideVolume || '0';
item.unit = "立方米"; item.unit = '立方米';
} }
} else if (item.label === "当年塌方量") { } else if (item.label === '当年塌方量') {
data.yearLandslideVolume = data.yearLandslideVolume.toFixed(2); data.yearLandslideVolume = data.yearLandslideVolume.toFixed(2);
if (data.yearLandslideVolume > 10000) { if (data.yearLandslideVolume > 10000) {
item.value = (data.yearLandslideVolume / 10000).toFixed(2) || "0"; item.value = (data.yearLandslideVolume / 10000).toFixed(2) || '0';
item.unit = "万立方米"; item.unit = '万立方米';
} else { } else {
item.value = data.yearLandslideVolume || "0"; item.value = data.yearLandslideVolume || '0';
item.unit = "立方米"; item.unit = '立方米';
} }
} else if (item.label === "本轮已损失") { } else if (item.label === '本轮已损失') {
data.roundTotalLossAmount = data.roundTotalLossAmount.toFixed(2); data.roundTotalLossAmount = data.roundTotalLossAmount.toFixed(2);
if (data.roundTotalLossAmount > 10000) { if (data.roundTotalLossAmount > 10000) {
item.value = (data.roundTotalLossAmount / 10000).toFixed(2) || "0"; item.value = (data.roundTotalLossAmount / 10000).toFixed(2) || '0';
item.unit = "亿元"; item.unit = '亿元';
} else { } else {
item.value = data.roundTotalLossAmount || "0"; item.value = data.roundTotalLossAmount || '0';
item.unit = "万元"; item.unit = '万元';
} }
} else if (item.label === "汛期已损失") { } else if (item.label === '汛期已损失') {
data.floodSeasonTotalLossAmount = data.floodSeasonTotalLossAmount = data.floodSeasonTotalLossAmount.toFixed(2);
data.floodSeasonTotalLossAmount.toFixed(2);
if (data.floodSeasonTotalLossAmount > 10000) { if (data.floodSeasonTotalLossAmount > 10000) {
item.value = item.value = (data.floodSeasonTotalLossAmount / 10000).toFixed(2) || '0';
(data.floodSeasonTotalLossAmount / 10000).toFixed(2) || "0"; item.unit = '亿元';
item.unit = "亿元";
} else { } else {
item.value = data.floodSeasonTotalLossAmount || "0"; item.value = data.floodSeasonTotalLossAmount || '0';
item.unit = "万元"; item.unit = '万元';
} }
} else if (item.label === "当年已损失") { } else if (item.label === '当年已损失') {
data.yearTotalLossAmount = data.yearTotalLossAmount.toFixed(2); data.yearTotalLossAmount = data.yearTotalLossAmount.toFixed(2);
if (data.yearTotalLossAmount > 10000) { if (data.yearTotalLossAmount > 10000) {
item.value = (data.yearTotalLossAmount / 10000).toFixed(2) || "0"; item.value = (data.yearTotalLossAmount / 10000).toFixed(2) || '0';
item.unit = "亿元"; item.unit = '亿元';
} else { } else {
item.value = data.yearTotalLossAmount || "0"; item.value = data.yearTotalLossAmount || '0';
item.unit = "万元"; item.unit = '万元';
} }
} }
}); });
} }
} catch (error) { } catch (error) {
console.error("获取灾害统计数据失败:", error); console.error('获取灾害统计数据失败:', error);
} }
}; };
// //
const extractAndSumNumbers = (value) => { const extractAndSumNumbers = value => {
// //
if (typeof value === "number") { if (typeof value === 'number') {
return value; return value;
} }
// 0 // 0
if (!value || typeof value !== "string") return 0; if (!value || typeof value !== 'string') return 0;
// //
const numbers = value.match(/\d+\.?\d*/g); const numbers = value.match(/\d+\.?\d*/g);
if (!numbers) return 0; if (!numbers) return 0;
@ -503,17 +488,17 @@ const extractAndSumNumbers = (value) => {
}; };
// //
const handleControlClick = (item) => { const handleControlClick = item => {
if (item.label === "封闭管控数") { if (item.label === '封闭管控数') {
emit("openClearanceSituation"); emit('openClearanceSituation');
} else if (item.label === "关闭驻地数") { } else if (item.label === '关闭驻地数') {
emit("openControlSituation"); emit('openControlSituation');
} }
}; };
// //
const handleBlockClick = () => { const handleBlockClick = () => {
emit("openClearanceSituation"); emit('openClearanceSituation');
}; };
// //
@ -522,112 +507,112 @@ const dateRange = ref([]);
// //
const resourceData = ref([ const resourceData = ref([
{ {
label: "全市普通公路抢险队伍", label: '全市普通公路抢险队伍',
value: "", value: '',
unit: "支", unit: '支',
iconClass: "icon-team", iconClass: 'icon-team',
img: icon1, img: icon1,
}, },
{ {
label: "人员", label: '人员',
value: "", value: '',
unit: "人", unit: '人',
iconClass: "icon-person", iconClass: 'icon-person',
img: icon2, img: icon2,
}, },
{ {
label: "储备装备", label: '储备装备',
value: "", value: '',
unit: "台", unit: '台',
iconClass: "icon-equip", iconClass: 'icon-equip',
img: icon3, img: icon3,
}, },
{ {
label: "物资", label: '物资',
value: "", value: '',
unit: "件", unit: '件',
iconClass: "icon-material", iconClass: 'icon-material',
img: icon4, img: icon4,
}, },
]); ]);
// //
const handleResourceClick = (item) => { const handleResourceClick = item => {
emit("openResourceDetail", item); emit('openResourceDetail', item);
}; };
// //
const controlData1 = ref([ const controlData1 = ref([
{ label: "封闭管控数", value: "40" }, { label: '封闭管控数', value: '40' },
{ label: "半幅通行数", value: "40" }, { label: '半幅通行数', value: '40' },
{ label: "限速(限车型)数", value: "24" }, { label: '限速(限车型)数', value: '24' },
{ label: "告警阻拦处数", value: "32" }, { label: '告警阻拦处数', value: '32' },
]); ]);
const controlData2 = [ const controlData2 = [
{ label: "停工项目数", value: "30" }, { label: '停工项目数', value: '30' },
{ label: "关闭驻地数", value: "42" }, { label: '关闭驻地数', value: '42' },
{ label: "转移撤离人员数", value: "58" }, { label: '转移撤离人员数', value: '58' },
]; ];
// //
const patrolData = [ const patrolData = [
{ label: "巡查路段数", value: "2" }, { label: '巡查路段数', value: '2' },
{ label: "巡查桥梁数", value: "1" }, { label: '巡查桥梁数', value: '1' },
{ label: "巡查边坡数", value: "6" }, { label: '巡查边坡数', value: '6' },
{ label: "巡查隧道数", value: "10" }, { label: '巡查隧道数', value: '10' },
{ label: "发现隐患数", value: "6" }, { label: '发现隐患数', value: '6' },
]; ];
// //
const rescueData = ref([ const rescueData = ref([
{ {
label: "本轮出动人次", label: '本轮出动人次',
value: "22341", value: '22341',
unit: "人次", unit: '人次',
iconClass: "icon-rescue-person", iconClass: 'icon-rescue-person',
img: icon11, img: icon11,
}, },
{ {
label: "本轮出动设备", label: '本轮出动设备',
value: "341", value: '341',
unit: "台次", unit: '台次',
iconClass: "icon-rescue-equip", iconClass: 'icon-rescue-equip',
img: icon12, img: icon12,
}, },
{ {
label: "清理塌方", label: '清理塌方',
value: "1367", value: '1367',
unit: "立方米", unit: '立方米',
iconClass: "icon-rescue-clear", iconClass: 'icon-rescue-clear',
img: icon13, img: icon13,
}, },
]); ]);
// - // -
const blockData = ref([ const blockData = ref([
{ label: "今日新增阻断数", current: "19", total: "23" }, { label: '今日新增阻断数', current: '19', total: '23' },
{ label: "本轮累计阻断数", current: "10", total: "23" }, { label: '本轮累计阻断数', current: '10', total: '23' },
]); ]);
// //
const deathData = ref({ label: "本轮因灾死亡人数", value: "5" }); const deathData = ref({ label: '本轮因灾死亡人数', value: '5' });
// //
const damageData = ref([ const damageData = ref([
{ label: "本轮塌方量", value: "23", unit: "万立方米", class: "blue" }, { label: '本轮塌方量', value: '23', unit: '万立方米', class: 'blue' },
{ label: "汛期塌方量", value: "23", unit: "万立方米", class: "blue" }, { label: '汛期塌方量', value: '23', unit: '万立方米', class: 'blue' },
{ label: "当年塌方量", value: "23", unit: "万立方米", class: "blue" }, { label: '当年塌方量', value: '23', unit: '万立方米', class: 'blue' },
{ label: "本轮已损失", value: "80", unit: "万元", class: "red" }, { label: '本轮已损失', value: '80', unit: '万元', class: 'red' },
{ label: "汛期已损失", value: "18", unit: "万元", class: "red" }, { label: '汛期已损失', value: '18', unit: '万元', class: 'red' },
{ label: "当年已损失", value: "350", unit: "万元", class: "red" }, { label: '当年已损失', value: '350', unit: '万元', class: 'red' },
]); ]);
// //
const majorEvent = "0"; const majorEvent = '0';
// watch // watch
const init = () => { const init = () => {
console.log("right.vue 刷新数据"); console.log('right.vue 刷新数据');
getYhYjllList(); getYhYjllList();
getYhYjllListMaterials(); getYhYjllListMaterials();
getControlStats(); getControlStats();
@ -646,13 +631,13 @@ onMounted(() => {
watch( watch(
() => getdateRange.value, () => getdateRange.value,
(newVal) => { newVal => {
console.log("right.vue 日期范围变化:", newVal); console.log('right.vue 日期范围变化:', newVal);
if (newVal && newVal.length === 2) { if (newVal && newVal.length === 2) {
} }
init(); init();
}, },
{ deep: true, immediate: true }, { deep: true, immediate: true }
); );
</script> </script>
@ -699,7 +684,7 @@ watch(
.section-header { .section-header {
display: flex; display: flex;
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(8);
height: vw(50); height: vw(50);
@ -721,7 +706,7 @@ watch(
justify-content: center; justify-content: center;
&::before { &::before {
content: "←"; content: '←';
color: #fff; color: #fff;
font-size: vw(10); font-size: vw(10);
} }
@ -751,12 +736,7 @@ watch(
padding: vw(4) vw(8); padding: vw(4) vw(8);
background: linear-gradient(270deg, rgba(18, 52, 97, 0) 0%, #203555 100%); background: linear-gradient(270deg, rgba(18, 52, 97, 0) 0%, #203555 100%);
border: 2px solid transparent; border: 2px solid transparent;
border-image: linear-gradient( border-image: linear-gradient(270deg, rgba(80, 145, 201, 0), rgba(39, 77, 153, 1)) 2 2;
270deg,
rgba(80, 145, 201, 0),
rgba(39, 77, 153, 1)
)
2 2;
border-radius: 6px; border-radius: 6px;
border-right: 0px; border-right: 0px;
@ -771,16 +751,16 @@ watch(
font-size: vw(18); font-size: vw(18);
&.icon-team::before { &.icon-team::before {
content: "👷"; content: '👷';
} }
&.icon-person::before { &.icon-person::before {
content: "👤"; content: '👤';
} }
&.icon-equip::before { &.icon-equip::before {
content: "🚛"; content: '🚛';
} }
&.icon-material::before { &.icon-material::before {
content: "📦"; content: '📦';
} }
} }
@ -837,7 +817,7 @@ watch(
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
// background: rgba(62, 106, 172, 0.36); // background: rgba(62, 106, 172, 0.36);
// box-shadow: inset 0px 0px 8px 0px #379bff; // box-shadow: inset 0px 0px 8px 0px #379bff;
background-image: url("../../assets/RiskWarning_img/路径 62@2x.png"); background-image: url('../../assets/RiskWarning_img/路径 62@2x.png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: right; background-position: right;
gap: vw(8); gap: vw(8);
@ -904,7 +884,7 @@ watch(
padding: vw(6) 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;
background-image: url("../../assets/RiskWarning_img/路径62@2x (1).png"); background-image: url('../../assets/RiskWarning_img/路径62@2x (1).png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: right; background-position: right;
@ -946,7 +926,7 @@ watch(
// 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; // border-radius: 6px;
background-image: url("../../assets/RiskWarning_img/路径62@2x (1).png"); background-image: url('../../assets/RiskWarning_img/路径62@2x (1).png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: right; background-position: right;
@ -960,13 +940,13 @@ watch(
margin-left: vw(5); margin-left: vw(5);
&.icon-rescue-person::before { &.icon-rescue-person::before {
content: "👷"; content: '👷';
} }
&.icon-rescue-equip::before { &.icon-rescue-equip::before {
content: "🚜"; content: '🚜';
} }
&.icon-rescue-clear::before { &.icon-rescue-clear::before {
content: "🏔️"; content: '🏔️';
} }
} }
@ -1030,7 +1010,7 @@ watch(
// display: grid; // display: grid;
// grid-template-columns: repeat(5, 1fr); // grid-template-columns: repeat(5, 1fr);
// gap: 10px; // gap: 10px;
background-image: url("../../assets/RiskWarning_img/编组22@2x.png"); background-image: url('../../assets/RiskWarning_img/编组22@2x.png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: center; background-position: center;
@ -1038,12 +1018,7 @@ watch(
width: 2px; width: 2px;
height: vw(40); height: vw(40);
margin: auto 0; margin: auto 0;
background: linear-gradient( background: linear-gradient(180deg, transparent 0%, #18f2f9 50%, transparent 100%);
180deg,
transparent 0%,
#18f2f9 50%,
transparent 100%
);
// margin: 0 auto; // margin: 0 auto;
} }
@ -1116,7 +1091,7 @@ watch(
padding: vw(4) 0; padding: vw(4) 0;
// background: rgba(64, 169, 255, 0.1); // background: rgba(64, 169, 255, 0.1);
// border-radius: 6px; // border-radius: 6px;
background-image: url("../../assets/RiskWarning_img/路径62@2x.png"); background-image: url('../../assets/RiskWarning_img/路径62@2x.png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: left; background-position: left;
@ -1159,7 +1134,7 @@ watch(
padding: vw(12); padding: vw(12);
// background: rgba(64, 169, 255, 0.1); // background: rgba(64, 169, 255, 0.1);
// border-radius: 6px; // border-radius: 6px;
background-image: url("../../assets/RiskWarning_img/编组5@2x.png"); background-image: url('../../assets/RiskWarning_img/编组5@2x.png');
background-size: 100% 100%; background-size: 100% 100%;
background-position: left; background-position: left;

View File

@ -1,9 +1,7 @@
<template> <template>
<div class="filter-header"> <div class="filter-header">
<div class="filter-container"> <div class="filter-container">
<span class="filter-item active" @click="handleDateRangeClick()" <span class="filter-item active" @click="handleDateRangeClick()">本轮</span>
>本轮</span
>
<div class="date-range-wrapper"> <div class="date-range-wrapper">
<el-date-picker <el-date-picker
v-model="dateRange" v-model="dateRange"
@ -18,22 +16,137 @@
/> />
</div> </div>
</div> </div>
<div class="hazard-stats" v-if="showHazardPopup">
<div
v-for="(item, index) in hazardStatsShowArr"
:key="index"
class="stat-item"
:class="item.class"
>
<span class="stat-label">{{ item.label }}</span>
<span class="stat-value-container display ai_center">
<span class="stat-value">{{ item.value }}</span>
<span class="stat-unit"></span>
</span>
</div>
</div>
<div class="road-stats" v-if="roadStats.length > 0">
<div v-for="(item, index) in roadStats" :key="index" class="stat-item">
<span class="stat-label">{{ item.label }}</span>
<span class="stat-value-container display ai_center">
<span class="stat-value">{{ item.value }}</span>
<span class="stat-unit"></span>
</span>
</div>
</div>
<!-- <img class="filter-icon-ai" src="../../assets/RiskWarning_img/AI1@2x.png" alt="" @click="handleAIClick" /> --> <!-- <img class="filter-icon-ai" src="../../assets/RiskWarning_img/AI1@2x.png" alt="" @click="handleAIClick" /> -->
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, watch, inject } from "vue"; import { ref, watch, inject, defineProps, nextTick, provide, onMounted } from 'vue';
import { Calendar } from "@element-plus/icons-vue"; import { Calendar } from '@element-plus/icons-vue';
import { request } from '@/utils/request';
const emit = defineEmits(["openAIResult", "dateRangeChange"]); const props = defineProps({
riskPointStats: {
type: Object,
default: () => ({}),
},
showHazardPopup: {
type: Boolean,
default: false,
},
roadvalArrtrue: {
type: Array,
default: () => [],
},
roadItem: {
type: Object,
default: () => ({}),
},
});
watch(
() => props.roadItem,
newVal => {
console.log('top.vue 收到路段信息:', newVal);
// roadvalArr.value = newVal;
}
);
watch(
() => props.showHazardPopup,
newShow => {
hazardStatsShowArr.value = JSON.parse(JSON.stringify([]));
hazardStats.value.forEach(item => {
item.value = 0;
item.show = false;
});
}
);
const emit = defineEmits(['openAIResult', 'dateRangeChange']);
// //
const triggerRefreshLeftData = inject("triggerRefreshLeftData"); const triggerRefreshLeftData = inject('triggerRefreshLeftData');
const dateRange = ref([]); const dateRange = ref([]);
//
const hazardStatsShowArr = ref([]);
const hazardStats = ref([
{ label: '重大路内隐患点', value: 0, show: false, type: '重大路内隐患点', isWithinRedLine: '是' },
{ label: '重大路外隐患点', value: 0, show: false, type: '重大路外隐患点', isWithinRedLine: '否' },
{ label: '较大路内隐患点', value: 0, show: false, type: '较大路内隐患点', isWithinRedLine: '是' },
{ label: '较大路外隐患点', value: 0, show: false, type: '较大路外隐患点', isWithinRedLine: '否' },
{ label: '一般路内隐患点', value: 0, show: false, type: '一般路内隐患点', isWithinRedLine: '是' },
{ label: '一般路外隐患点', value: 0, show: false, type: '一般路外隐患点', isWithinRedLine: '否' },
{ label: '风险点总数', value: 0, show: false, type: '风险点总数', isWithinRedLine: '' },
]);
//
const roadStats = ref([
{ label: '高风险路段', value: 0, type: '高风险路段' },
{ label: '较高风险路段', value: 0, type: '较高风险路段' },
{ label: '中风险路段', value: 0, type: '中风险路段' },
{ label: '低风险路段', value: 0, type: '低风险路段' },
{ label: '风险点总数', value: 0, type: '风险点总数' },
]);
watch(
() => props.riskPointStats,
newStats => {
console.log('top.vue 收到风险点统计数据:', newStats);
if (newStats) {
hazardStatsShowArr.value = [];
hazardStats.value.forEach(item => {
if (
item.label.includes(newStats.riskLevel) &&
newStats.isWithinRedLine == item.isWithinRedLine &&
newStats.value >= 0
) {
item.value = newStats.value;
item.show = true;
}
if (item.show) {
hazardStatsShowArr.value.push(item);
hazardStats.value[6].show = true;
}
});
hazardStats.value[6].value =
hazardStats.value[0].value +
hazardStats.value[1].value +
hazardStats.value[2].value +
hazardStats.value[3].value +
hazardStats.value[4].value +
hazardStats.value[5].value;
}
},
{ immediate: true, deep: true }
);
// 23:59:59 // 23:59:59
const setEndOfDay = (date) => { const setEndOfDay = date => {
if (!date) return date; if (!date) return date;
const d = new Date(date); const d = new Date(date);
d.setHours(23, 59, 59, 999); d.setHours(23, 59, 59, 999);
@ -50,9 +163,9 @@ watch(
dateRange, dateRange,
(newVal, oldVal) => { (newVal, oldVal) => {
// //
console.log("dateRange 变化:", newVal, oldVal); console.log('dateRange 变化:', newVal, oldVal);
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) { if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
console.log("dateRange 发生变化:", newVal); console.log('dateRange 发生变化:', newVal);
// 23:59:59 // 23:59:59
if (newVal && newVal.length === 2 && newVal[1]) { if (newVal && newVal.length === 2 && newVal[1]) {
newVal[1] = setEndOfDay(newVal[1]); newVal[1] = setEndOfDay(newVal[1]);
@ -62,15 +175,51 @@ watch(
// triggerRefreshLeftData(); // triggerRefreshLeftData();
// } // }
// //
emit("dateRangeChange", newVal); emit('dateRangeChange', newVal);
} }
}, },
{ deep: true }, { deep: true }
); );
const handleAIClick = () => { const handleAIClick = () => {
emit("openAIResult"); emit('openAIResult');
}; };
//
const fetchRiskLevelCount = async () => {
try {
const res = await request({
url: '/snow-ops-platform/risk-point/risk-level-count',
method: 'GET',
});
console.log('风险等级统计数据:', res);
if (res.code === '00000' && res.data) {
//
const data = res.data;
let roadTotal = 0;
roadStats.value.forEach(item => {
data.forEach(d => {
debugger;
console.log(item.label, d.level);
console.log(item.label.includes(d.level));
if (item.label.includes(d.level)) {
roadTotal += Number(d.count);
item.value = Number(d.count);
}
});
});
roadStats.value[4].value = roadTotal;
console.log(roadStats.value);
}
} catch (error) {
console.error('获取风险等级统计数据失败:', error);
}
};
//
onMounted(() => {
fetchRiskLevelCount();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -82,8 +231,8 @@ const handleAIClick = () => {
.filter-header { .filter-header {
padding: vw(10); padding: vw(10);
display: flex; // display: flex;
justify-content: space-between; // justify-content: space-between;
// align-items: center; // align-items: center;
// //
@ -104,6 +253,7 @@ const handleAIClick = () => {
min-height: 18px; min-height: 18px;
gap: vw(8); gap: vw(8);
font-size: vw(13); font-size: vw(13);
margin-bottom: vw(20);
.filter-item { .filter-item {
color: #fff; color: #fff;
@ -165,4 +315,91 @@ const handleAIClick = () => {
min-height: 48px; min-height: 48px;
cursor: pointer; cursor: pointer;
} }
//
.hazard-stats {
width: min-content;
display: grid;
background: url('@/assets/RiskWarning_img/隐患点弹窗背景@2x.png') no-repeat top left;
background-size: 100% 100%;
grid-template-columns: repeat(7, 1fr);
margin-bottom: vw(20);
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
// gap: vw(4);
&:last-child {
border-right: none;
}
.stat-label {
font-size: vw(14);
padding: vw(8) vw(15);
// background: #0e365d;
color: rgba(255, 255, 255, 0.8);
white-space: nowrap;
}
.stat-value-container {
padding: vw(4) vw(10);
}
.stat-value {
font-size: vw(18);
font-weight: bold;
color: #ff4d4f;
}
.stat-unit {
font-size: vw(14);
color: #fff;
}
}
}
//
.road-stats {
padding: vw(10);
width: min-content;
display: grid;
background: url('@/assets/RiskWarning_img/隐患点弹窗背景@2x.png') no-repeat top left;
background-size: 100% 100%;
grid-template-columns: repeat(5, 1fr);
margin-bottom: vw(20);
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
gap: vw(4);
padding: 0 vw(10);
&:last-child {
border-right: none;
}
.stat-label {
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
white-space: nowrap;
}
.stat-value-container {
display: flex;
align-items: center;
gap: vw(2);
.stat-value {
font-size: vw(18);
font-weight: bold;
color: #ff4d4f;
}
.stat-unit {
font-size: vw(14);
color: rgba(255, 255, 255, 0.8);
}
}
}
}
</style> </style>