Merge branch 'dev' of http://222.212.85.86:8222/bdzl2/bxztApp into dev
This commit is contained in:
commit
97ca34d622
BIN
packages/screen/src/assets/RiskWarning_img/区县弹窗背景@2x.png
Normal file
BIN
packages/screen/src/assets/RiskWarning_img/区县弹窗背景@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
232
packages/screen/src/views/RiskWarning/Dialog/centerInfoCard.vue
Normal file
232
packages/screen/src/views/RiskWarning/Dialog/centerInfoCard.vue
Normal file
@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<div class="center-info-card-container" v-if="visible" @click="handleClick">
|
||||
<div
|
||||
class="center-info-card"
|
||||
:style="{ backgroundImage: `url(${districtIcon})` }"
|
||||
>
|
||||
<!-- 标题栏 -->
|
||||
<div class="card-header">
|
||||
<div class="header-left">
|
||||
<img class="location-icon" :src="locationIcon" alt="" />
|
||||
<span class="header-title">{{ title }}</span>
|
||||
</div>
|
||||
<span class="header-arrow">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 内容区域 -->
|
||||
<div class="card-content">
|
||||
<div class="info-row">
|
||||
<span class="info-text">人数:{{ item?.population || "-" }}人</span>
|
||||
<span class="info-text">
|
||||
<span v-if="item?.type == 'project'">项目:</span>
|
||||
<span v-else>路段:</span>
|
||||
<span>{{ item?.entityCount || "-" }}</span>
|
||||
<span v-if="item?.type == 'project'">个</span>
|
||||
<span v-else>条</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { ArrowRight, Close } from "@element-plus/icons-vue";
|
||||
import districtIcon from "../../../assets/MaMap_img/区县弹窗背景@2x.png";
|
||||
import locationIcon from "../../../assets/MaMap_img/区县icon@2x.png";
|
||||
|
||||
const props = defineProps({
|
||||
// 是否显示卡片
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 卡片类型:'second' | 'third' | null
|
||||
type: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
// 标题
|
||||
title: {
|
||||
type: String,
|
||||
default: "潼南",
|
||||
},
|
||||
// 数据列表
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 数据项
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
// 人数
|
||||
peopleCount: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
// 路段数
|
||||
roadCount: {
|
||||
type: [Number, String],
|
||||
default: 117,
|
||||
},
|
||||
// 是否显示关闭按钮
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["click", "close", "itemClick", "onClick"]);
|
||||
|
||||
// 是否显示卡片(兼容旧版本)
|
||||
const showCard = computed(() => {
|
||||
// 如果有 visible 属性,直接使用
|
||||
if (props.visible !== undefined) {
|
||||
return props.visible;
|
||||
}
|
||||
// 否则使用旧版本的类型判断
|
||||
return props.type === "second" || props.type === "third";
|
||||
});
|
||||
|
||||
// 获取公路类型文本
|
||||
const getRoadTypeText = (roadType) => {
|
||||
const roadTypeMap = {
|
||||
national: "国省道",
|
||||
rural: "农村公路",
|
||||
};
|
||||
return roadTypeMap[roadType] || roadType;
|
||||
};
|
||||
|
||||
// 点击事件(兼容旧版本)
|
||||
const handleClick = () => {
|
||||
console.log("centerInfoCard clicked, type:", props.type);
|
||||
// 触发 onClick 事件
|
||||
emit("onClick");
|
||||
// 同时触发旧版本的 click 事件
|
||||
emit("click", props.type);
|
||||
};
|
||||
|
||||
// 关闭事件
|
||||
const handleClose = () => {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
// 数据项点击事件
|
||||
const handleItemClick = (item) => {
|
||||
emit("itemClick", item);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@function vw($px) {
|
||||
@return calc($px / 1920 * 100vw);
|
||||
}
|
||||
|
||||
.center-info-card-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-width: 150px;
|
||||
z-index: 1000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
// 中心数据展示卡片
|
||||
.center-info-card {
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
z-index: 50;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
overflow: hidden;
|
||||
border-radius: vw(8);
|
||||
|
||||
&:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
// 标题栏
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: vw(10) vw(14);
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: vw(6);
|
||||
|
||||
.location-icon {
|
||||
width: vw(16);
|
||||
height: vw(16);
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: vw(14);
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.header-arrow,
|
||||
.header-close {
|
||||
font-size: vw(14);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 内容区域
|
||||
.card-content {
|
||||
padding: vw(8) vw(14) vw(12);
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.info-text {
|
||||
font-size: vw(12);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.data-list {
|
||||
.data-item {
|
||||
padding: vw(4) 0;
|
||||
|
||||
.item-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: vw(2);
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: vw(11);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.item-value {
|
||||
font-size: vw(11);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -17,7 +17,13 @@
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">影响区域</span>
|
||||
<el-select :teleported="false" v-model="filterForm.region" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.district"
|
||||
placeholder="请选择"
|
||||
class="filter-select"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in regionOptions"
|
||||
:key="item.value"
|
||||
@ -28,7 +34,13 @@
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">类型</span>
|
||||
<el-select :teleported="false" v-model="filterForm.type" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.type"
|
||||
placeholder="请选择"
|
||||
class="filter-select"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in typeOptions"
|
||||
:key="item.value"
|
||||
@ -39,7 +51,14 @@
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">管控措施</span>
|
||||
<el-select :teleported="false" v-model="filterForm.controlMeasure" placeholder="请选择" class="filter-select" clearable>
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.roadConditionType"
|
||||
placeholder="请选择"
|
||||
class="filter-select"
|
||||
clearable
|
||||
@change="handleFilterChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in controlMeasureOptions"
|
||||
:key="item.value"
|
||||
@ -66,8 +85,10 @@
|
||||
</template>
|
||||
|
||||
<!-- 管控措施列插槽 -->
|
||||
<template #controlMeasure="{ row }">
|
||||
<span :class="['control-tag', getControlClass(row.controlMeasure)]">{{ row.controlMeasure }}</span>
|
||||
<template #roadConditionType="{ row }">
|
||||
<span :class="['control-tag', getControlClass(row.roadConditionType)]">{{
|
||||
row.roadConditionType
|
||||
}}</span>
|
||||
</template>
|
||||
|
||||
<!-- 操作列插槽 -->
|
||||
@ -80,8 +101,13 @@
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
import { regionOptions, typeOptions, controlMeasureOptions } from "../component/index.js";
|
||||
import {
|
||||
regionOptions,
|
||||
typeOptions,
|
||||
controlMeasureOptions,
|
||||
} from "../component/index.js";
|
||||
import BaseDialog from "../component/baseDialog.vue";
|
||||
import { request } from "@/utils/request";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
@ -94,9 +120,9 @@ const emit = defineEmits(["update:visible", "close", "detail"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
region: "",
|
||||
district: "",
|
||||
type: "",
|
||||
controlMeasure: "",
|
||||
roadConditionType: "",
|
||||
});
|
||||
|
||||
// 影响区域选项
|
||||
@ -113,65 +139,25 @@ const tableHeight = ref(300);
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = ref([
|
||||
{ prop: 'id', label: '序号', width: '50' },
|
||||
{ prop: 'region', label: '影响区域', width: '80' },
|
||||
{ prop: 'routeNo', label: '线路编号', width: '80' },
|
||||
{ prop: 'stakeNo', label: '起止桩号', width: '100', slot: 'stakeNo' },
|
||||
{ prop: 'location', label: '路况位置', width: '100', slot: 'location' },
|
||||
{ prop: 'occurrenceTime', label: '发生时间', width: '140' },
|
||||
{ prop: 'routeNo2', label: '线路编号', width: '80' },
|
||||
{ prop: 'type', label: '类型', width: '80' },
|
||||
{ prop: 'controlMeasure', label: '管控措施', width: '100', slot: 'controlMeasure' },
|
||||
{ prop: 'operation', label: '操作', width: '80', slot: 'operation' },
|
||||
{ prop: "id", label: "序号", width: "" },
|
||||
{ prop: "district", label: "影响区域", width: "" },
|
||||
{ prop: "routeNo", label: "线路编号", width: "" },
|
||||
{ prop: "stakeNo", label: "起止桩号", width: "", slot: "stakeNo" },
|
||||
{ prop: "location", label: "路况位置", width: "", slot: "location" },
|
||||
{ prop: "occurrenceTime", label: "发生时间", width: "" },
|
||||
{ prop: "routeNo2", label: "线路编号", width: "" },
|
||||
{ prop: "type", label: "类型", width: "" },
|
||||
{
|
||||
prop: "roadConditionType",
|
||||
label: "管控措施",
|
||||
width: "",
|
||||
slot: "roadConditionType",
|
||||
},
|
||||
{ prop: "operation", label: "操作", width: "", slot: "operation" },
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "巫溪县",
|
||||
routeNo: "G242",
|
||||
stakeNo: "336.800-338.850",
|
||||
location: "三星乡五斗村",
|
||||
occurrenceTime: "2025-08-11 04:53:42",
|
||||
routeNo2: "G242",
|
||||
type: "边坡坍塌",
|
||||
controlMeasure: "全幅封闭",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "万州区",
|
||||
routeNo: "G242",
|
||||
stakeNo: "338.800-338.850",
|
||||
location: "三星乡五斗村",
|
||||
occurrenceTime: "2025-08-11 04:53:42",
|
||||
routeNo2: "G242",
|
||||
type: "边坡坍塌",
|
||||
controlMeasure: "正常通行",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "沙坪坝区",
|
||||
routeNo: "G319",
|
||||
stakeNo: "120.500-122.000",
|
||||
location: "沙坪坝镇",
|
||||
occurrenceTime: "2025-08-10 14:30:00",
|
||||
routeNo2: "G319",
|
||||
type: "路面塌陷",
|
||||
controlMeasure: "半幅封闭",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
region: "渝中区",
|
||||
routeNo: "G212",
|
||||
stakeNo: "88.200-89.100",
|
||||
location: "渝中大道",
|
||||
occurrenceTime: "2025-08-09 09:15:30",
|
||||
routeNo2: "G212",
|
||||
type: "桥梁损坏",
|
||||
controlMeasure: "限制通行",
|
||||
},
|
||||
]);
|
||||
const tableData = ref([]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
@ -199,10 +185,10 @@ const visiblePages = computed(() => {
|
||||
// 获取管控措施样式类
|
||||
const getControlClass = (measure) => {
|
||||
const classMap = {
|
||||
"全幅封闭": "control-close",
|
||||
"半幅封闭": "control-half",
|
||||
"正常通行": "control-normal",
|
||||
"限制通行": "control-limit",
|
||||
全幅封闭: "control-close",
|
||||
半幅封闭: "control-half",
|
||||
正常通行: "control-normal",
|
||||
限制通行: "control-limit",
|
||||
};
|
||||
return classMap[measure] || "";
|
||||
};
|
||||
@ -228,11 +214,59 @@ const handleCurrentChange = (val) => {
|
||||
currentPage.value = val;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 筛选条件改变时触发
|
||||
const handleFilterChange = () => {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
};
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// 转换管控措施类型
|
||||
let measureType = 0;
|
||||
if (filterForm.value.roadConditionType === "全幅封闭") {
|
||||
measureType = 1;
|
||||
} else if (filterForm.value.roadConditionType === "半幅封闭") {
|
||||
measureType = 2;
|
||||
} else if (filterForm.value.roadConditionType === "限速") {
|
||||
measureType = 3;
|
||||
} else if (filterForm.value.roadConditionType === "告警阻拦") {
|
||||
measureType = 4;
|
||||
}
|
||||
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/sm-event/dashboard/control-list",
|
||||
method: "GET",
|
||||
params: {
|
||||
pageNum: currentPage.value,
|
||||
pageSize: pageSize.value,
|
||||
measureType: measureType,
|
||||
},
|
||||
});
|
||||
|
||||
if (res.code === "00000" && res.data) {
|
||||
const data = res.data;
|
||||
// 转换数据格式
|
||||
tableData.value = data.records.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
district: item.district || "-",
|
||||
routeNo: item.routeNo || "-",
|
||||
stakeNo: `${item.startStakeNo}-${item.endStakeNo}` || "-",
|
||||
location: item.occurLocation || "-",
|
||||
occurrenceTime: item.occurTime || "-",
|
||||
routeNo2: item.routeNo || "-",
|
||||
type: item.roadConditionType || "-",
|
||||
roadConditionType: item.roadConditionType || "-",
|
||||
expectRecoverTime: item.expectRecoverTime || "-",
|
||||
eventStatus: item.eventStatus || "-",
|
||||
};
|
||||
});
|
||||
total.value = data.total;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取抢通情况数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
@ -243,7 +277,7 @@ watch(
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
@ -19,78 +19,20 @@
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-cards">
|
||||
<div
|
||||
@click="handleClick('0')"
|
||||
v-for="(item, index) in impactData"
|
||||
:key="index"
|
||||
@click="handleClick(index)"
|
||||
class="stat-card"
|
||||
:style="{
|
||||
backgroundImage: `url(${cardType === '0' ? selectedIcon : unselectedIcon})`,
|
||||
backgroundImage: `url(${cardType == index ? selectedIcon : unselectedIcon})`,
|
||||
backgroundSize: '100% 100%',
|
||||
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">
|
||||
<span class="stat-label">影响桥梁</span>
|
||||
<span class="stat-value">(1430)</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>
|
||||
<span class="stat-label">{{ item.name }}</span>
|
||||
<span class="stat-value">{{ item.count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -100,7 +42,8 @@
|
||||
<template #filter>
|
||||
<div class="filter-row">
|
||||
<div class="filter-item">
|
||||
<el-select :teleported="false"
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.pointType"
|
||||
size="small"
|
||||
placeholder="影响点类型"
|
||||
@ -115,7 +58,8 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select :teleported="false"
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.pointLevel"
|
||||
size="small"
|
||||
placeholder="影响点等级"
|
||||
@ -130,7 +74,8 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="filter-item">
|
||||
<el-select :teleported="false"
|
||||
<el-select
|
||||
:teleported="false"
|
||||
v-model="filterForm.region"
|
||||
size="small"
|
||||
placeholder="影响区域"
|
||||
@ -191,16 +136,86 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 一般人员(路长履职)列插槽 -->
|
||||
<template #generalStaff="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.generalStaff.name }}</span>
|
||||
<span class="person-phone">{{ row.generalStaff.phone }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 项目类型专用插槽 -->
|
||||
<!-- 吹哨人列插槽 -->
|
||||
<template #whistleblower="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.whistleblower?.name || "-" }}</span>
|
||||
<span class="person-phone">{{ row.whistleblower?.phone || "-" }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 建设单位包保责任人列插槽 -->
|
||||
<template #constructionUnit="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.constructionUnit?.name || "-" }}</span>
|
||||
<span class="person-phone">{{
|
||||
row.constructionUnit?.phone || "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 施工单位包保责任人列插槽 -->
|
||||
<template #constructionDept="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.constructionDept?.name || "-" }}</span>
|
||||
<span class="person-phone">{{
|
||||
row.constructionDept?.phone || "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 驻地包保责任人列插槽 -->
|
||||
<template #siteResponsible="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.siteResponsible?.name || "-" }}</span>
|
||||
<span class="person-phone">{{
|
||||
row.siteResponsible?.phone || "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 区县级包保责任人列插槽 -->
|
||||
<template #countyResponsible="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{
|
||||
row.countyResponsible?.name || "-"
|
||||
}}</span>
|
||||
<span class="person-phone">{{
|
||||
row.countyResponsible?.phone || "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 市级包保责任人列插槽 -->
|
||||
<template #cityResponsible="{ row }">
|
||||
<div class="person-info">
|
||||
<span class="person-name">{{ row.cityResponsible?.name || "-" }}</span>
|
||||
<span class="person-phone">{{
|
||||
row.cityResponsible?.phone || "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 操作列插槽 -->
|
||||
<template #operation="{ row }">
|
||||
<template #operation="{ row }" fixed="right">
|
||||
<span class="detail-link" @click="handleDetail(row)">详情</span>
|
||||
</template>
|
||||
</base-dialog>
|
||||
</template>
|
||||
|
||||
<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 { request } from "@/utils/request";
|
||||
import {
|
||||
pointTypeOptions,
|
||||
pointLevelOptions,
|
||||
@ -235,8 +250,8 @@ const filterForm = ref({
|
||||
region: "",
|
||||
});
|
||||
|
||||
// 表格列配置
|
||||
const tableColumns = ref([
|
||||
// 统一的表格列配置(桥梁、边坡、隧道、路段使用)
|
||||
const unifiedColumns = [
|
||||
{ prop: "id", label: "序号", width: "" },
|
||||
{ prop: "region", label: "影响区域", width: "" },
|
||||
{ prop: "pointType", label: "影响点类型", width: "" },
|
||||
@ -256,59 +271,171 @@ const tableColumns = ref([
|
||||
slot: "maintenance",
|
||||
},
|
||||
{ prop: "roadKeeper", label: "护路员", width: "", slot: "roadKeeper" },
|
||||
{ prop: "operation", label: "操作", width: "", slot: "operation" },
|
||||
]);
|
||||
{
|
||||
prop: "generalStaff",
|
||||
label: "一般人员(路长履职)",
|
||||
width: "",
|
||||
slot: "generalStaff",
|
||||
},
|
||||
{
|
||||
prop: "operation",
|
||||
label: "操作",
|
||||
width: "80",
|
||||
slot: "operation",
|
||||
fixed: "right",
|
||||
},
|
||||
];
|
||||
|
||||
// 项目类型专用表格列配置
|
||||
const projectColumns = [
|
||||
{ prop: "id", label: "序号", width: "60" },
|
||||
{ prop: "region", label: "影响区域", width: "" },
|
||||
{ prop: "pointType", label: "影响点类型", width: "" },
|
||||
{ prop: "siteName", label: "驻地名称", width: "" },
|
||||
{
|
||||
prop: "whistleblower",
|
||||
label: "吹哨人",
|
||||
width: "",
|
||||
slot: "whistleblower",
|
||||
},
|
||||
{
|
||||
prop: "constructionUnit",
|
||||
label: "建设单位包保责任人",
|
||||
width: "",
|
||||
slot: "constructionUnit",
|
||||
},
|
||||
{
|
||||
prop: "constructionDept",
|
||||
label: "施工单位包保责任人",
|
||||
width: "",
|
||||
slot: "constructionDept",
|
||||
},
|
||||
{
|
||||
prop: "siteResponsible",
|
||||
label: "驻地包保责任人",
|
||||
width: "",
|
||||
slot: "siteResponsible",
|
||||
},
|
||||
{
|
||||
prop: "countyResponsible",
|
||||
label: "区县级包保责任人",
|
||||
width: "",
|
||||
slot: "countyResponsible",
|
||||
},
|
||||
{
|
||||
prop: "cityResponsible",
|
||||
label: "市级包保责任人",
|
||||
width: "",
|
||||
slot: "cityResponsible",
|
||||
},
|
||||
];
|
||||
|
||||
// 为兼容旧代码,保留变量名引用
|
||||
const bridgeColumns = unifiedColumns;
|
||||
const slopeColumns = unifiedColumns;
|
||||
const tunnelColumns = unifiedColumns;
|
||||
const roadColumns = unifiedColumns;
|
||||
|
||||
// 当前表格列配置
|
||||
const tableColumns = ref(bridgeColumns);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
region: "重庆市",
|
||||
pointType: "边坡",
|
||||
pointLocation: "武汉-大理(K1452+951至K1462+209)",
|
||||
pointLevel: "一般隐患",
|
||||
levelClass: "level-normal",
|
||||
trafficDept: { name: "罗宸", phone: "17623865172" },
|
||||
roadOrg: { name: "李海平", phone: "13708320801" },
|
||||
maintenance: { name: "苏祖兵", phone: "13594331090" },
|
||||
roadKeeper: { name: "凌承礼", phone: "1592393704" },
|
||||
},
|
||||
const tableData = ref([]);
|
||||
// 影响点数据
|
||||
const impactData = ref([
|
||||
{ name: "影响桥梁", count: 0, icon: Icon0 },
|
||||
{ name: "影响边坡", count: 0, icon: Icon1 },
|
||||
{ name: "影响隧道", count: 0, icon: Icon2 },
|
||||
{ name: "影响项目", count: 0, icon: Icon3 },
|
||||
{ name: "影响路段", count: 0, icon: Icon4 },
|
||||
]);
|
||||
// 顶部卡片数据
|
||||
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: "项目",
|
||||
};
|
||||
|
||||
// 转换英文name为中文
|
||||
const convertedData = data.map((item) => {
|
||||
const name = nameMap[item.name] || item.name;
|
||||
return { ...item, name };
|
||||
});
|
||||
convertedData.forEach((item) => {
|
||||
impactData.value.forEach((stat) => {
|
||||
if (stat.name.includes(item.extension)) {
|
||||
stat.count = item.count || 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载柱状图数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const cardType = ref("0");
|
||||
|
||||
// 根据 cardType 获取对应的表格列配置
|
||||
const getColumnsByType = (type) => {
|
||||
const typeMap = {
|
||||
0: bridgeColumns,
|
||||
1: slopeColumns,
|
||||
2: tunnelColumns,
|
||||
3: projectColumns,
|
||||
4: roadColumns,
|
||||
};
|
||||
return typeMap[type] || bridgeColumns;
|
||||
};
|
||||
|
||||
// 根据 cardType 获取对应的 API 路径
|
||||
const getApiUrlByType = (type) => {
|
||||
const urlMap = {
|
||||
0: "/snow-ops-platform/weather-warning/affected-object/bridge",
|
||||
1: "/snow-ops-platform/weather-warning/affected-object/slope",
|
||||
2: "/snow-ops-platform/weather-warning/affected-object/tunnel",
|
||||
3: "/snow-ops-platform/weather-warning/affected-object/project",
|
||||
4: "/snow-ops-platform/weather-warning/affected-object/road-section",
|
||||
};
|
||||
return (
|
||||
urlMap[type] || "/snow-ops-platform/weather-warning/affected-object/bridge"
|
||||
);
|
||||
};
|
||||
|
||||
const cardType = ref("");
|
||||
// 点击卡片切换
|
||||
const handleClick = (type) => {
|
||||
cardType.value = type;
|
||||
tableData.value = [];
|
||||
cardType.value = type + "";
|
||||
// 切换表格列配置
|
||||
tableColumns.value = getColumnsByType(cardType.value);
|
||||
// 重置分页并获取数据
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
const total = ref(0);
|
||||
|
||||
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
|
||||
|
||||
@ -358,11 +485,353 @@ const handleCurrentChange = (val) => {
|
||||
currentPage.value = val;
|
||||
fetchData();
|
||||
};
|
||||
// 获取时间参数
|
||||
const getTimeParams = () => {
|
||||
// 默认时间范围:当月1号到当前时间
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(now.getDate()).padStart(2, "0");
|
||||
const hours = String(now.getHours()).padStart(2, "0");
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
const seconds = String(now.getSeconds()).padStart(2, "0");
|
||||
|
||||
return {
|
||||
// start: `${year}-${month}-01 00:00:00`,
|
||||
// end: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`,
|
||||
start: "2025-07-01 00:00:00",
|
||||
end: "2025-08-01 00:00:00",
|
||||
limit: pageSize.value,
|
||||
offset: currentPage.value,
|
||||
};
|
||||
};
|
||||
// 处理数据为统一格式
|
||||
const processUnifiedData = (item, type) => {
|
||||
// 根据类型获取影响点类型名称
|
||||
const typeMap = {
|
||||
0: "桥梁",
|
||||
1: "边坡",
|
||||
2: "隧道",
|
||||
3: "项目",
|
||||
4: "路段",
|
||||
};
|
||||
|
||||
// 获取等级样式类
|
||||
const getLevelClass = (level) => {
|
||||
const levelMap = {
|
||||
红色预警: "level-red",
|
||||
橙色预警: "level-orange",
|
||||
黄色预警: "level-yellow",
|
||||
蓝色预警: "level-blue",
|
||||
高风险: "level-red",
|
||||
中风险: "level-orange",
|
||||
低风险: "level-blue",
|
||||
};
|
||||
return levelMap[level] || "";
|
||||
};
|
||||
|
||||
// 获取影响点等级
|
||||
const pointLevel =
|
||||
item.riskLevel ||
|
||||
item.warningLevel ||
|
||||
item.level ||
|
||||
item.GL1_PDDJ ||
|
||||
item.GL1_JSDJ ||
|
||||
"-";
|
||||
|
||||
// 基础数据
|
||||
const baseData = {
|
||||
id: item.id,
|
||||
// 影响区域
|
||||
region:
|
||||
item.GL1_QXMC ||
|
||||
item.COUNTY ||
|
||||
item.county ||
|
||||
item.region ||
|
||||
item.ADMINISTRATIVE_REGION ||
|
||||
"-",
|
||||
// 影响点类型
|
||||
pointType: typeMap[type] || "-",
|
||||
// 影响点位置(根据类型取不同字段)
|
||||
pointLocation:
|
||||
item.GL1_QLMC ||
|
||||
item.NAME ||
|
||||
item.GL1_SDMC ||
|
||||
item.PROJECT_NAME ||
|
||||
item.GL1_LXBH ||
|
||||
item.name ||
|
||||
"-",
|
||||
// 影响点等级
|
||||
pointLevel: pointLevel,
|
||||
levelClass: getLevelClass(pointLevel),
|
||||
// 交通主管部门负责人
|
||||
trafficDept: {
|
||||
// name: item.trafficDeptName || item.trafficManager || "-",
|
||||
phone: item.trafficDeptPhone || item.trafficManagerPhone || "-",
|
||||
name: "-",
|
||||
phone: "-",
|
||||
},
|
||||
// 公路机构责任人
|
||||
roadOrg: {
|
||||
// name: item.roadOrgName || item.roadManager || "-",
|
||||
// phone: item.roadOrgPhone || item.roadManagerPhone || "-",
|
||||
name: "-",
|
||||
phone: "-",
|
||||
},
|
||||
// 养护站负责人
|
||||
maintenance: {
|
||||
// name: item.maintenanceName || item.maintenanceManager || "-",
|
||||
// phone: item.maintenancePhone || item.maintenanceManagerPhone || "-",
|
||||
name: "-",
|
||||
phone: "-",
|
||||
},
|
||||
// 护路员
|
||||
roadKeeper: {
|
||||
// name: item.roadKeeperName || item.roadKeeper || "-",
|
||||
// phone: item.roadKeeperPhone || item.roadKeeperPhone || "-",
|
||||
name: "-",
|
||||
phone: "-",
|
||||
},
|
||||
// 一般人员(路长履职)
|
||||
generalStaff: {
|
||||
// name: item.generalStaffName || item.roadChief || "-",
|
||||
// phone: item.generalStaffPhone || item.roadChiefPhone || "-",
|
||||
name: "-",
|
||||
phone: "-",
|
||||
},
|
||||
// 保留原始数据供详情使用
|
||||
rawData: item,
|
||||
};
|
||||
|
||||
// 桥梁类型特殊处理(根据BASE_GLQL桥梁信息表字典)
|
||||
if (type === "0") {
|
||||
return {
|
||||
...baseData,
|
||||
// 影响区域 - 使用区县名称
|
||||
region: item.GL1_QXMC || "-",
|
||||
// 影响点位置 - 使用桥梁名称
|
||||
pointLocation: item.GL1_QLMC || "-",
|
||||
// 影响点等级 - 使用技术状况评级等级
|
||||
pointLevel: item.GL1_JSZKPJDJ || item.GL1_PDDJ || item.GL1_CSFXDJ || "-",
|
||||
levelClass: getLevelClass(
|
||||
item.GL1_JSZKPJDJ || item.GL1_PDDJ || item.GL1_CSFXDJ,
|
||||
),
|
||||
// // 交通主管部门负责人 - 管理单位负责人(GL1_DWFZR)
|
||||
// trafficDept: {
|
||||
// name: item.GL1_DWFZR || "-",
|
||||
// phone: item.GL1_GLDWDH || "-",
|
||||
// },
|
||||
// // 公路机构责任人 - 统计负责人(GL1_TJFZR)
|
||||
// roadOrg: {
|
||||
// name: item.GL1_TJFZR || "-",
|
||||
// phone: item.GL1_TJFZRDH || "-",
|
||||
// },
|
||||
// // 养护站负责人 - 养护单位责任人(GL1_YHDWDH)
|
||||
// maintenance: {
|
||||
// name: item.GL1_GLDWMC || "-",
|
||||
// phone: item.GL1_YHDWDH || "-",
|
||||
// },
|
||||
// // 护路员 - 填报人
|
||||
// roadKeeper: {
|
||||
// name: item.GL1_TBRXM || "-",
|
||||
// phone: item.GL1_TBRDH || "-",
|
||||
// },
|
||||
// // 一般人员(路长履职)- 桥梁工程师(GL1_QLGCS)
|
||||
// generalStaff: {
|
||||
// name: item.GL1_QLGCS || "-",
|
||||
// phone: item.GL1_QLGCSDH || "-",
|
||||
// },
|
||||
};
|
||||
}
|
||||
|
||||
// 隧道类型特殊处理(根据BASE_GLSD隧道信息表字典)
|
||||
if (type === "2") {
|
||||
return {
|
||||
...baseData,
|
||||
// 影响区域 - 使用区县名称
|
||||
region: item.GL1_QXMC || item.GL1_QXBM || "-",
|
||||
// 影响点位置 - 使用隧道名称
|
||||
pointLocation: item.GL1_SDMC || "-",
|
||||
// 影响点等级 - 使用评定等级
|
||||
pointLevel: item.GL1_PDDJ || item.GL1_TJJGPDDJ || item.GL1_SDYHDJ || "-",
|
||||
levelClass: getLevelClass(
|
||||
item.GL1_PDDJ || item.GL1_TJJGPDDJ || item.GL1_SDYHDJ,
|
||||
),
|
||||
// // 交通主管部门负责人 - 管养单位行政领导(GL1_GYDWXZLD)
|
||||
// trafficDept: {
|
||||
// name: item.GL1_GYDWXZLD || "-",
|
||||
// phone: item.GL1_GYDWXZLDDH || "-",
|
||||
// },
|
||||
// // 公路机构责任人 - 隧道路政员(GL1_SDLZY)
|
||||
// roadOrg: {
|
||||
// name: item.GL1_SDLZY || "-",
|
||||
// phone: item.GL1_SDLZYDH || "-",
|
||||
// },
|
||||
// // 养护站负责人 - 隧道养护工(GL1_SDYHG)
|
||||
// maintenance: {
|
||||
// name: item.GL1_SDYHG || "-",
|
||||
// phone: item.GL1_SDYHGDH || "-",
|
||||
// },
|
||||
// // 护路员 - 隧道信息填报人(GL1_SDXXTBR)
|
||||
// roadKeeper: {
|
||||
// name: item.GL1_SDXXTBR || "-",
|
||||
// phone: item.GL1_SDXXTBRDH || "-",
|
||||
// },
|
||||
// // 一般人员(路长履职)- 管养单位养护工程师(GL1_GYDWYHGCS)
|
||||
// generalStaff: {
|
||||
// name: item.GL1_GYDWYHGCS || "-",
|
||||
// phone: item.GL1_GYDWYHGSCSDH || "-",
|
||||
// },
|
||||
};
|
||||
}
|
||||
|
||||
// 路段类型特殊处理(根据BASE_XJLD路线信息表字典)
|
||||
if (type === "4") {
|
||||
return {
|
||||
...baseData,
|
||||
// 影响区域 - 使用区县ID对应名称
|
||||
region: item.GL1_QXMC || item.GL1_QXID || "-",
|
||||
// 影响点位置 - 使用路线名称+起终点名称
|
||||
pointLocation: item.GL1_LXMC || item.GL1_LXBH || item.name || "-",
|
||||
// 影响点等级 - 使用技术等级
|
||||
pointLevel: item.GL1_JSDJ || item.GL1_XZDJ || "-",
|
||||
levelClass: getLevelClass(item.GL1_JSDJ || item.GL1_XZDJ),
|
||||
// // 交通主管部门负责人 - 管理单位(GL1_GLDW)
|
||||
// trafficDept: {
|
||||
// name: item.GL1_GLDW || "-",
|
||||
// phone: item.GL1_GLDWDH || "-",
|
||||
// },
|
||||
// // 公路机构责任人 - 起点名称作为路段责任人标识
|
||||
// roadOrg: {
|
||||
// name: item.GL1_QDMC || "-",
|
||||
// phone: item.GL1_QDZH ? String(item.GL1_QDZH) : "-",
|
||||
// },
|
||||
// // 养护站负责人 - 终点名称
|
||||
// maintenance: {
|
||||
// name: item.GL1_ZDMC || "-",
|
||||
// phone: item.GL1_ZDZH ? String(item.GL1_ZDZH) : "-",
|
||||
// },
|
||||
// // 护路员 - 路线编号
|
||||
// roadKeeper: {
|
||||
// name: item.GL1_LXBH || "-",
|
||||
// phone: item.GL1_LXBM || "-",
|
||||
// },
|
||||
// // 一般人员(路长履职)- 技术等级文本
|
||||
// generalStaff: {
|
||||
// name: item.GL1_JSDJTXT || item.GL1_JSDJ || "-",
|
||||
// phone: item.GL1_TZSJ || "-",
|
||||
// },
|
||||
};
|
||||
}
|
||||
|
||||
// 项目类型特殊处理(根据SQL字段映射)
|
||||
if (type === "3") {
|
||||
return {
|
||||
...baseData,
|
||||
// 影响区域 - 使用COUNTY字段
|
||||
region: item.COUNTY || item.county || item.county_name || "-",
|
||||
// 影响点位置 - 使用项目名称
|
||||
pointLocation: item.PROJECT_NAME || item.projectName || item.name || "-",
|
||||
// 驻地名称
|
||||
siteName:
|
||||
item.SITE_NAME ||
|
||||
item.siteName ||
|
||||
item.PROJECT_NAME ||
|
||||
item.projectName ||
|
||||
"-",
|
||||
// 吹哨人 - WHISTLEBLOWER_NAME / WHISTLEBLOWER_PHONE
|
||||
whistleblower: {
|
||||
name: item.WHISTLEBLOWER_NAME || item.whistleblowerName || "-",
|
||||
phone: item.WHISTLEBLOWER_PHONE || item.whistleblowerPhone || "-",
|
||||
},
|
||||
// 建设单位包保责任人 - OWNER_RESPONSIBLE_PERSON / OWNER_RESPONSIBLE_PHONE
|
||||
constructionUnit: {
|
||||
name:
|
||||
item.OWNER_RESPONSIBLE_PERSON || item.ownerResponsiblePerson || "-",
|
||||
phone:
|
||||
item.OWNER_RESPONSIBLE_PHONE || item.ownerResponsiblePhone || "-",
|
||||
},
|
||||
// 施工单位包保责任人 - CONSTRUCTOR_RESPONSIBLE_PERSON / CONSTRUCTOR_RESPONSIBLE_PHONE
|
||||
constructionDept: {
|
||||
name:
|
||||
item.CONSTRUCTOR_RESPONSIBLE_PERSON ||
|
||||
item.constructorResponsiblePerson ||
|
||||
"-",
|
||||
phone:
|
||||
item.CONSTRUCTOR_RESPONSIBLE_PHONE ||
|
||||
item.constructorResponsiblePhone ||
|
||||
"-",
|
||||
},
|
||||
// 驻地包保责任人 - SITE_RESPONSIBLE_PERSON / SITE_RESPONSIBLE_PHONE
|
||||
siteResponsible: {
|
||||
name: item.SITE_RESPONSIBLE_PERSON || item.siteResponsiblePerson || "-",
|
||||
phone: item.SITE_RESPONSIBLE_PHONE || item.siteResponsiblePhone || "-",
|
||||
},
|
||||
// 区县级包保责任人 - DISTRICT_RESPONSIBLE_PERSON / DISTRICT_RESPONSIBLE_PHONE
|
||||
countyResponsible: {
|
||||
name:
|
||||
item.DISTRICT_RESPONSIBLE_PERSON ||
|
||||
item.districtResponsiblePerson ||
|
||||
"-",
|
||||
phone:
|
||||
item.DISTRICT_RESPONSIBLE_PHONE ||
|
||||
item.districtResponsiblePhone ||
|
||||
"-",
|
||||
},
|
||||
// 市级包保责任人 - CITY_RESPONSIBLE_PERSON / CITY_RESPONSIBLE_PHONE
|
||||
cityResponsible: {
|
||||
name: item.CITY_RESPONSIBLE_PERSON || item.cityResponsiblePerson || "-",
|
||||
phone: item.CITY_RESPONSIBLE_PHONE || item.cityResponsiblePhone || "-",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return baseData;
|
||||
};
|
||||
|
||||
// 根据类型处理数据(统一格式)
|
||||
const processDataByType = (item, type) => {
|
||||
return processUnifiedData(item, type);
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
const fetchData = async () => {
|
||||
console.log("获取第", currentPage.value, "页数据, 类型:", cardType.value);
|
||||
try {
|
||||
const timeParams = getTimeParams();
|
||||
|
||||
// 根据 cardType 获取对应的 API URL
|
||||
const apiUrl = getApiUrlByType(cardType.value);
|
||||
|
||||
const res = await request({
|
||||
url: apiUrl,
|
||||
method: "GET",
|
||||
params: timeParams,
|
||||
});
|
||||
|
||||
if (res.code === "00000" && res.data) {
|
||||
// 处理返回数据
|
||||
const allData = res.data;
|
||||
total.value = allData.length || 0;
|
||||
|
||||
// 客户端分页:计算当前页的数据范围
|
||||
const startIndex = (currentPage.value - 1) * pageSize.value;
|
||||
const endIndex = startIndex + pageSize.value;
|
||||
const currentPageData = allData.slice(startIndex, endIndex);
|
||||
|
||||
tableData.value = currentPageData.map((item, index) => ({
|
||||
...processDataByType(item, cardType.value),
|
||||
id: startIndex + index + 1,
|
||||
}));
|
||||
} else {
|
||||
tableData.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取影响点数据失败:", error);
|
||||
tableData.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
@ -370,6 +839,13 @@ watch(
|
||||
() => props.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
filterForm.value = {
|
||||
pointType: "",
|
||||
pointLevel: "",
|
||||
region: "",
|
||||
};
|
||||
cardType.value = "0";
|
||||
loadBarChartData();
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
}
|
||||
@ -468,42 +944,6 @@ watch(
|
||||
}
|
||||
}
|
||||
|
||||
// 表格列样式
|
||||
.level-tag {
|
||||
display: inline-block;
|
||||
padding: vw(2) vw(8);
|
||||
border-radius: vw(4);
|
||||
font-size: vw(11);
|
||||
|
||||
&.level-normal {
|
||||
background-color: rgba(250, 219, 95, 0.2);
|
||||
color: #fadb5f;
|
||||
border: 1px solid rgba(250, 219, 95, 0.4);
|
||||
}
|
||||
|
||||
&.level-serious {
|
||||
background-color: rgba(255, 77, 79, 0.2);
|
||||
color: #ff4d4f;
|
||||
border: 1px solid rgba(255, 77, 79, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.person-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: vw(2);
|
||||
|
||||
.person-name {
|
||||
font-size: vw(12);
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.person-phone {
|
||||
font-size: vw(11);
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
.detail-link {
|
||||
color: #40a9ff;
|
||||
cursor: pointer;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">预警等级</span>
|
||||
<el-select
|
||||
v-model="filterForm.warningLevel"
|
||||
v-model="filterForm.riskLeve"
|
||||
placeholder="请选择"
|
||||
class="filter-select el-select"
|
||||
clearable
|
||||
@ -36,7 +36,7 @@
|
||||
<div class="filter-item">
|
||||
<span class="filter-label">影响区域</span>
|
||||
<el-select
|
||||
v-model="filterForm.region"
|
||||
v-model="filterForm.countyName"
|
||||
placeholder="请选择"
|
||||
class="filter-select"
|
||||
clearable
|
||||
@ -89,9 +89,9 @@
|
||||
</template>
|
||||
|
||||
<!-- 预警等级列插槽 -->
|
||||
<template #warningLevel="{ row }">
|
||||
<span :class="['warning-level-tag', getWarningClass(row.warningLevel)]">{{
|
||||
row.warningLevel
|
||||
<template #riskLeve="{ row }">
|
||||
<span :class="['warning-level-tag', getWarningClass(row.riskLeve)]">{{
|
||||
row.riskLeve
|
||||
}}</span>
|
||||
</template>
|
||||
|
||||
@ -105,14 +105,15 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { Close } from "@element-plus/icons-vue";
|
||||
import { ref, computed, watch, onMounted } from "vue";
|
||||
import { Close, Calendar } from "@element-plus/icons-vue";
|
||||
import {
|
||||
warningLevelOptions,
|
||||
regionOptions,
|
||||
isEndedOptions,
|
||||
} from "../component/index.js";
|
||||
import baseDialog from "../component/baseDialog.vue";
|
||||
import { request } from "@/utils/request";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
@ -121,24 +122,42 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "impactClick"]);
|
||||
|
||||
// 初始化日期范围(当月)
|
||||
const getDefaultDateRange = () => {
|
||||
const now = new Date();
|
||||
const start = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59);
|
||||
return [start, end];
|
||||
return ['', ''];
|
||||
};
|
||||
onMounted(() => {
|
||||
filterForm.value = {
|
||||
riskLeve: "",
|
||||
countyName: "",
|
||||
isEnded: "",
|
||||
dateRange: dateRange.value,
|
||||
};
|
||||
fetchWarningData();
|
||||
});
|
||||
|
||||
// 日期范围器
|
||||
const dateRange = ref([]);
|
||||
const dateRange = ref(getDefaultDateRange());
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
riskLeve: "",
|
||||
countyName: "",
|
||||
isEnded: "",
|
||||
dateRange: dateRange.value,
|
||||
});
|
||||
|
||||
// 处理日期范围变化
|
||||
const handleDateChange = (val) => {
|
||||
filterForm.value.dateRange = val;
|
||||
};
|
||||
|
||||
const emit = defineEmits(["update:visible", "close", "impactClick"]);
|
||||
|
||||
// 筛选表单
|
||||
const filterForm = ref({
|
||||
warningLevel: "",
|
||||
region: "",
|
||||
isEnded: "",
|
||||
dateRange: [],
|
||||
});
|
||||
|
||||
// 预警等级选项
|
||||
// 已从 index.js 导入
|
||||
|
||||
@ -155,13 +174,18 @@ const tableHeight = ref(300);
|
||||
const tableColumns = ref([
|
||||
{ prop: "index", label: "序号", width: "" },
|
||||
{
|
||||
prop: "warningLevel",
|
||||
prop: "riskLeve",
|
||||
label: "预警等级",
|
||||
width: "",
|
||||
slot: "warningLevel",
|
||||
slot: "riskLeve",
|
||||
},
|
||||
{
|
||||
label: "来源",
|
||||
prop: "source",
|
||||
width: "",
|
||||
},
|
||||
{ prop: "weatherType", label: "气象类型", width: "" },
|
||||
{ prop: "region", label: "影响区域", width: "" },
|
||||
{ prop: "countyName", label: "影响区域", width: "" },
|
||||
{ prop: "warningTime", label: "生效时间", width: "" },
|
||||
{ prop: "endTime", label: "失效时间", width: "" },
|
||||
{
|
||||
@ -173,54 +197,95 @@ const tableColumns = ref([
|
||||
]);
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([
|
||||
{
|
||||
id: 1,
|
||||
index: 1,
|
||||
warningLevel: "红色预警",
|
||||
weatherType: "暴雨",
|
||||
region: "重庆市",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactCount: 0,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
index: 2,
|
||||
warningLevel: "橙色预警",
|
||||
weatherType: "暴雨",
|
||||
region: "万州区",
|
||||
warningTime: "2025-08-11 04:53:42",
|
||||
endTime: "2025-08-11 04:53:42",
|
||||
impactCount: 1,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
index: 3,
|
||||
warningLevel: "黄色预警",
|
||||
weatherType: "大风",
|
||||
region: "沙坪坝区",
|
||||
warningTime: "2025-08-10 16:20:15",
|
||||
endTime: "2025-08-10 20:30:00",
|
||||
impactCount: 3,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
index: 4,
|
||||
warningLevel: "蓝色预警",
|
||||
weatherType: "雷电",
|
||||
region: "渝中区",
|
||||
warningTime: "2025-08-09 09:15:30",
|
||||
endTime: "2025-08-09 12:00:00",
|
||||
impactCount: 2,
|
||||
},
|
||||
]);
|
||||
tableData.value.push(...tableData.value);
|
||||
tableData.value.push(...tableData.value);
|
||||
const tableData = ref([]);
|
||||
|
||||
// 分页
|
||||
const currentPage = ref(1);
|
||||
const pageSize = ref(10);
|
||||
const total = ref(36);
|
||||
const total = ref(0);
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 获取预警数据
|
||||
const fetchWarningData = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
offset: currentPage.value,
|
||||
limit: pageSize.value,
|
||||
start: "",
|
||||
end: "",
|
||||
riskLevel: "",
|
||||
weatherType: "",
|
||||
isExpire: "",
|
||||
countyName: "",
|
||||
};
|
||||
|
||||
// 添加筛选条件
|
||||
if (filterForm.value.riskLeve) {
|
||||
params.riskLevel = filterForm.value.riskLeve;
|
||||
}
|
||||
if (filterForm.value.countyName) {
|
||||
params.countyName = filterForm.value.countyName;
|
||||
}
|
||||
if (
|
||||
filterForm.value.isEnded !== undefined &&
|
||||
filterForm.value.isEnded !== ""
|
||||
) {
|
||||
params.isExpire = filterForm.value.isEnded;
|
||||
}
|
||||
if (filterForm.value.dateRange && filterForm.value.dateRange.length === 2) {
|
||||
params.start = formatDateTime(filterForm.value.dateRange[0]);
|
||||
params.end = formatDateTime(filterForm.value.dateRange[1]);
|
||||
}
|
||||
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/weather-warning/affected-count/_by_weather",
|
||||
method: "GET",
|
||||
params,
|
||||
});
|
||||
|
||||
if (res.code === "00000" && res.data) {
|
||||
// 处理返回数据
|
||||
const list = res.data.data || res.data.records || [];
|
||||
total.value = res.data.total || 0;
|
||||
|
||||
tableData.value = list.map((item, index) => ({
|
||||
index: index + 1,
|
||||
riskLeve: item.riskLeve || "-",
|
||||
weatherType: item.weatherType || "-",
|
||||
countyName: item.countyName || "-",
|
||||
source: item.source || "-",
|
||||
warningTime: item.startTime || "-",
|
||||
endTime: item.endTime || "-",
|
||||
impactCount: item.affectedCount || 0,
|
||||
}));
|
||||
} else {
|
||||
tableData.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取预警数据失败:", error);
|
||||
tableData.value = [];
|
||||
total.value = 0;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (date) => {
|
||||
if (!date) return "";
|
||||
const d = new Date(date);
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
const hours = String(d.getHours()).padStart(2, "0");
|
||||
const minutes = String(d.getMinutes()).padStart(2, "0");
|
||||
const seconds = String(d.getSeconds()).padStart(2, "0");
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
// 获取预警等级样式类
|
||||
const getWarningClass = (level) => {
|
||||
@ -247,18 +312,12 @@ const handleImpactClick = (item) => {
|
||||
// 分页操作
|
||||
const handleSizeChange = (val) => {
|
||||
pageSize.value = val;
|
||||
fetchData();
|
||||
fetchWarningData();
|
||||
};
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
currentPage.value = val;
|
||||
fetchData();
|
||||
};
|
||||
|
||||
// 获取数据
|
||||
const fetchData = () => {
|
||||
console.log("获取第", currentPage.value, "页数据");
|
||||
// 实际项目中调用API获取数据
|
||||
fetchWarningData();
|
||||
};
|
||||
|
||||
// 监听visible变化
|
||||
@ -267,10 +326,37 @@ watch(
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
currentPage.value = 1;
|
||||
fetchData();
|
||||
fetchWarningData();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// 监听筛选条件变化
|
||||
watch(
|
||||
() => filterForm.value,
|
||||
() => {
|
||||
currentPage.value = 1;
|
||||
fetchWarningData();
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
// 同步 dateRange 和 filterForm.dateRange
|
||||
watch(
|
||||
() => dateRange.value,
|
||||
(newVal) => {
|
||||
filterForm.value.dateRange = newVal;
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => filterForm.value.dateRange,
|
||||
(newVal) => {
|
||||
dateRange.value = newVal;
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -415,6 +501,6 @@ watch(
|
||||
:deep(.el-range-editor.el-input__wrapper) {
|
||||
width: 240px !important;
|
||||
height: 30px !important;
|
||||
background-color: #122C46 !important;
|
||||
background-color: #122c46 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -25,14 +25,30 @@
|
||||
:type="mapInfoDialogType"
|
||||
:data="mapInfoDialogData"
|
||||
/>
|
||||
<centerInfoCard
|
||||
:visible="centerCardVisible"
|
||||
:title="centerCardTitle"
|
||||
:dataList="centerCardDataList"
|
||||
@close="closeCenterCard"
|
||||
@itemClick="handleCenterCardItemClick"
|
||||
@click="handleCenterCardClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, watch, defineExpose } from "vue";
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
watch,
|
||||
defineExpose,
|
||||
h,
|
||||
render,
|
||||
} from "vue";
|
||||
import axios from "axios";
|
||||
import { request } from "@/utils/request";
|
||||
import TongnanCenterCardDialog from "@/views/RiskWarning/Dialog/tongnanCenterCardDialog.vue";
|
||||
import TongnanCenterCardDialog from "../Dialog/tongnanCenterCardDialog.vue";
|
||||
|
||||
import projectIcon from "../../../assets/MaMap_img/项目@2x.png";
|
||||
import bridgeIcon from "../../../assets/MaMap_img/桥梁icon@2x.png";
|
||||
@ -43,6 +59,7 @@ import rescueTeamIcon from "../../../assets/MaMap_img/队伍icon@2x.png";
|
||||
|
||||
import tunnelInfoDialog from "../Dialog/tunnelInfoDialog.vue";
|
||||
import mapInfoDialog from "../Dialog/mapInfoDialog.vue";
|
||||
import centerInfoCard from "../Dialog/centerInfoCard.vue";
|
||||
|
||||
const mapContainer = ref(null);
|
||||
const loading = ref(false);
|
||||
@ -62,7 +79,12 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
// 定义 emits
|
||||
const emit = defineEmits(["districtClick"]);
|
||||
const emit = defineEmits([
|
||||
"districtClick",
|
||||
"openTongnanTeam",
|
||||
"openResponseSituation",
|
||||
"openTongnanResponsible",
|
||||
]);
|
||||
|
||||
// 当前选中的区县
|
||||
const selectedDistrict = ref(null);
|
||||
@ -77,6 +99,14 @@ const mapInfoDialogVisible = ref(false);
|
||||
const mapInfoDialogType = ref("project");
|
||||
const mapInfoDialogData = ref({});
|
||||
|
||||
// 中心信息卡片弹窗
|
||||
const centerCardVisible = ref(false);
|
||||
const centerCardTitle = ref("调度统计");
|
||||
const centerCardDataList = ref([]);
|
||||
|
||||
// 地图上显示的区县卡片标记
|
||||
let countyCardMarkers = [];
|
||||
|
||||
// 打开地图信息弹窗
|
||||
const openMapInfoDialog = (type, data) => {
|
||||
mapInfoDialogType.value = type;
|
||||
@ -84,6 +114,164 @@ const openMapInfoDialog = (type, data) => {
|
||||
mapInfoDialogVisible.value = true;
|
||||
};
|
||||
|
||||
// 清除地图上的区县卡片标记
|
||||
const clearCountyCardMarkers = () => {
|
||||
countyCardMarkers.forEach((marker) => {
|
||||
// 清理 Vue 组件
|
||||
if (marker._vueContainer) {
|
||||
render(null, marker._vueContainer);
|
||||
}
|
||||
if (mapInstance) {
|
||||
mapInstance.removeLayer(marker);
|
||||
}
|
||||
});
|
||||
countyCardMarkers = [];
|
||||
};
|
||||
|
||||
// 在地图上显示区县卡片
|
||||
const showCountyCardsOnMap = (dataList) => {
|
||||
if (!mapInstance || !geoJsonLayer) {
|
||||
console.warn("地图未初始化,无法显示区县卡片");
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除之前的卡片标记
|
||||
clearCountyCardMarkers();
|
||||
|
||||
if (!dataList || dataList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 简化区县名称
|
||||
const simplifyName = (name) => {
|
||||
return name
|
||||
.replace("土家族苗族自治县", "")
|
||||
.replace("苗族土家族自治县", "")
|
||||
.replace("自治县", "")
|
||||
.replace("区", "")
|
||||
.replace("县", "");
|
||||
};
|
||||
|
||||
// 遍历数据列表,为每个区县创建卡片
|
||||
dataList.forEach((item) => {
|
||||
const countyName = item.countyName || item.name;
|
||||
if (!countyName) return;
|
||||
|
||||
const targetName = simplifyName(countyName);
|
||||
|
||||
// 查找对应的区县图层
|
||||
let targetLayer = null;
|
||||
geoJsonLayer.eachLayer((layer) => {
|
||||
const layerName = layer.feature?.properties?.name || "";
|
||||
if (simplifyName(layerName) === targetName) {
|
||||
targetLayer = layer;
|
||||
}
|
||||
});
|
||||
|
||||
if (targetLayer) {
|
||||
// 获取区县的中心点
|
||||
const bounds = targetLayer.getBounds();
|
||||
const center = bounds.getCenter();
|
||||
|
||||
// 创建一个容器元素用于挂载 Vue 组件
|
||||
const container = document.createElement("div");
|
||||
container.className = "county-card-wrapper";
|
||||
|
||||
// 使用 Vue 的 h 函数创建组件虚拟节点
|
||||
const vnode = h(centerInfoCard, {
|
||||
visible: true,
|
||||
title: countyName,
|
||||
dataList: [item],
|
||||
item: item,
|
||||
onClose: () => {
|
||||
closeCenterCard();
|
||||
},
|
||||
onItemClick: (clickedItem) => {
|
||||
handleCenterCardItemClick(clickedItem);
|
||||
},
|
||||
});
|
||||
|
||||
// 渲染组件到容器
|
||||
render(vnode, container);
|
||||
|
||||
// 创建自定义图标,使用渲染后的 HTML
|
||||
const customIcon = window.L.divIcon({
|
||||
className: "county-card-icon",
|
||||
html: container.innerHTML,
|
||||
iconSize: [150, 40],
|
||||
iconAnchor: [110, 60],
|
||||
});
|
||||
|
||||
// 创建标记
|
||||
const marker = window.L.marker(center, {
|
||||
icon: customIcon,
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
// 添加点击事件到 marker
|
||||
marker.on("click", () => {
|
||||
console.log("centerInfoCard clicked, county:", countyName);
|
||||
// 调用处理函数
|
||||
handleCenterCardItemClick(item);
|
||||
// 移动地图到该位置
|
||||
mapInstance.setView(center, 10);
|
||||
// 触发点击事件
|
||||
emit("districtClick", {
|
||||
name: countyName,
|
||||
data: item,
|
||||
});
|
||||
});
|
||||
|
||||
marker.addTo(mapInstance);
|
||||
countyCardMarkers.push(marker);
|
||||
|
||||
// 保存容器引用以便后续清理
|
||||
marker._vueContainer = container;
|
||||
}
|
||||
});
|
||||
|
||||
// 调整地图视角以显示所有卡片
|
||||
if (countyCardMarkers.length > 0) {
|
||||
const group = new window.L.featureGroup(countyCardMarkers);
|
||||
mapInstance.fitBounds(group.getBounds().pad(0.2));
|
||||
}
|
||||
};
|
||||
|
||||
// 获取公路类型文本
|
||||
const getRoadTypeText = (roadType) => {
|
||||
const roadTypeMap = {
|
||||
national: "国省道",
|
||||
rural: "农村公路",
|
||||
};
|
||||
return roadTypeMap[roadType] || roadType;
|
||||
};
|
||||
|
||||
// 打开中心信息卡片弹窗
|
||||
const openCenterCard = (data) => {
|
||||
centerCardDataList.value = data.dataList || [];
|
||||
centerCardTitle.value = data.title || "调度统计";
|
||||
centerCardVisible.value = true;
|
||||
|
||||
// 在地图上显示区县卡片
|
||||
showCountyCardsOnMap(data.dataList);
|
||||
};
|
||||
|
||||
// 关闭中心信息卡片弹窗
|
||||
const closeCenterCard = () => {
|
||||
centerCardVisible.value = false;
|
||||
clearCountyCardMarkers();
|
||||
};
|
||||
|
||||
// 处理中心卡片项点击
|
||||
const handleCenterCardItemClick = (item) => {
|
||||
console.log("点击了卡片项:", item);
|
||||
// 根据区县名称定位地图
|
||||
if (item.countyName || item.name) {
|
||||
const countyName = item.countyName || item.name;
|
||||
locateToDistrict(countyName);
|
||||
}
|
||||
};
|
||||
|
||||
// 打开隧道信息弹窗(兼容旧代码)
|
||||
const openTunnelDialog = (data) => {
|
||||
openMapInfoDialog("tunnel", data);
|
||||
@ -151,7 +339,7 @@ const getAffectedCountyData = async () => {
|
||||
getAffectedTunnelData();
|
||||
getAffectedBridgeData();
|
||||
getAffectedRoadSectionData();
|
||||
getEmergencyForceData();
|
||||
// getEmergencyForceData();
|
||||
|
||||
loadMapData();
|
||||
}
|
||||
@ -330,7 +518,13 @@ const clearProjectMarkers = () => {
|
||||
mapInstance.removeLayer(marker);
|
||||
}
|
||||
});
|
||||
clearCountyCardMarkers();
|
||||
projectMarkers = [];
|
||||
|
||||
// 关闭所有弹窗
|
||||
tunnelDialogVisible.value = false;
|
||||
mapInfoDialogVisible.value = false;
|
||||
centerCardVisible.value = false;
|
||||
};
|
||||
|
||||
// 在地图上添加项目标记
|
||||
@ -374,15 +568,6 @@ const addProjectMarkers = (data, iconUrl, type = "project") => {
|
||||
const latNum = parseFloat(lat);
|
||||
const lngNum = parseFloat(lng);
|
||||
|
||||
console.log(
|
||||
"项目坐标:",
|
||||
item.NAME || item.name,
|
||||
"纬度:",
|
||||
latNum,
|
||||
"经度:",
|
||||
lngNum,
|
||||
);
|
||||
|
||||
if (!isNaN(latNum) && !isNaN(lngNum)) {
|
||||
const marker = window.L.marker([latNum, lngNum], {
|
||||
icon: projectIconObj,
|
||||
@ -709,7 +894,7 @@ const initMap = (geoJsonData) => {
|
||||
affectedCountyData.value.byName[districtName]
|
||||
) {
|
||||
const districtData = affectedCountyData.value.byName[districtName];
|
||||
console.log(districtData.levels);
|
||||
// console.log(districtData.levels);
|
||||
fillColor = getMainWarningColor(districtData.levels);
|
||||
fillOpacity = 1; // 有预警时稍微不透明一些
|
||||
}
|
||||
@ -945,10 +1130,67 @@ onUnmounted(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// 根据区县名称定位地图
|
||||
const locateToDistrict = (countyName) => {
|
||||
if (!mapInstance || !geoJsonLayer) {
|
||||
console.warn("地图未初始化,无法定位");
|
||||
return;
|
||||
}
|
||||
|
||||
// 简化区县名称
|
||||
const simplifyName = (name) => {
|
||||
return name
|
||||
.replace("土家族苗族自治县", "")
|
||||
.replace("苗族土家族自治县", "")
|
||||
.replace("自治县", "")
|
||||
.replace("区", "")
|
||||
.replace("县", "");
|
||||
};
|
||||
|
||||
const targetName = simplifyName(countyName);
|
||||
console.log("定位到区县:", countyName, "简化后:", targetName);
|
||||
|
||||
// 查找对应的区县图层
|
||||
let targetLayer = null;
|
||||
geoJsonLayer.eachLayer((layer) => {
|
||||
const layerName = layer.feature?.properties?.name || "";
|
||||
if (simplifyName(layerName) === targetName) {
|
||||
targetLayer = layer;
|
||||
}
|
||||
});
|
||||
|
||||
if (targetLayer) {
|
||||
// 获取区县的中心点
|
||||
const bounds = targetLayer.getBounds();
|
||||
const center = bounds.getCenter();
|
||||
|
||||
// 移动地图到该中心点并放大
|
||||
mapInstance.setView(center, 10);
|
||||
|
||||
// 高亮显示该区县
|
||||
if (selectedLayer) {
|
||||
geoJsonLayer.resetStyle(selectedLayer);
|
||||
}
|
||||
targetLayer.setStyle({
|
||||
fillColor: "#ff7a00",
|
||||
fillOpacity: 0.6,
|
||||
weight: 3,
|
||||
color: "#ff4d4f",
|
||||
});
|
||||
selectedLayer = targetLayer;
|
||||
|
||||
console.log("已定位到区县:", countyName, "中心点:", center);
|
||||
} else {
|
||||
console.warn("未找到区县:", countyName);
|
||||
}
|
||||
};
|
||||
|
||||
// 暴露方法给父组件调用
|
||||
defineExpose({
|
||||
getEmergencyForceData,
|
||||
clearProjectMarkers,
|
||||
openCenterCard,
|
||||
locateToDistrict,
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1110,4 +1352,27 @@ defineExpose({
|
||||
padding: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// 区县卡片样式
|
||||
:deep(.county-card-icon) {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
|
||||
.center-info-card-container {
|
||||
width: 100%;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.center-info-card {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(24, 144, 255, 0.5);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -34,11 +34,11 @@
|
||||
<slot name="filter"></slot>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-section" v-if="props.tableData.length > 0">
|
||||
<div class="table-section">
|
||||
<el-table
|
||||
:data="props.tableData"
|
||||
:height="props.tableHeight"
|
||||
style="width: 100%"
|
||||
style="width: 100%; min-height: 300px"
|
||||
:header-cell-style="headerCellStyle"
|
||||
:cell-style="cellStyle"
|
||||
size="small"
|
||||
@ -59,10 +59,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div
|
||||
class="pagination"
|
||||
v-if="props.showPagination && props.tableData.length > 0"
|
||||
>
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
:current-page="props.currentPage"
|
||||
:page-size="props.pageSize"
|
||||
@ -468,4 +465,9 @@ const cellStyle = () => {
|
||||
:deep(.el-popper__arrow::after) {
|
||||
border-color: #122c46 !important;
|
||||
}
|
||||
|
||||
:deep(.el-pager li.is-active) {
|
||||
background-color: #2598ff !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
/* 防止样式被覆盖,提高优先级 */
|
||||
.custom-date-picker {
|
||||
z-index: 10000 !important;
|
||||
/* 弹出框整体背景色 */
|
||||
background-color: #122C45 !important;
|
||||
/* 弹出框边框(主题色) */
|
||||
@ -14,9 +15,11 @@
|
||||
/* 可选:阴影效果 */
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
|
||||
.el-date-editor .el-range-input {
|
||||
color: #289DFF !important;
|
||||
}
|
||||
|
||||
/* ========== 1. 顶部栏(年月切换区域) ========== */
|
||||
.custom-date-picker .el-date-picker__header,
|
||||
.custom-date-picker .el-picker-panel__header {
|
||||
@ -144,6 +147,7 @@
|
||||
.custom-date-picker .popper__arrow {
|
||||
border-bottom-color: #122C45 !important;
|
||||
}
|
||||
|
||||
.custom-date-picker .popper__arrow::after {
|
||||
border-bottom-color: #122C45 !important;
|
||||
}
|
||||
@ -156,7 +160,7 @@
|
||||
|
||||
/* 范围选择左右面板 */
|
||||
.custom-date-picker .el-date-range-picker__content {
|
||||
background-color: #122C45 !important;
|
||||
background-color: #152D47 !important;
|
||||
}
|
||||
|
||||
/* 范围选择头部 */
|
||||
@ -172,10 +176,13 @@
|
||||
color: #FFFFFF !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.el-date-table td.in-range .el-date-table-cell{
|
||||
background-color: #27374A !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
/* 范围选择 - 中间区间 */
|
||||
.custom-date-picker .el-date-table td.in-range .el-date-table-cell__text {
|
||||
background-color: rgba(40, 157, 255, 0.25) !important;
|
||||
background-color: #3E91BC !important;
|
||||
color: #FFFFFF !important;
|
||||
border-radius: 0;
|
||||
}
|
||||
@ -207,7 +214,7 @@
|
||||
.custom-date-picker .el-time-spinner__item.active {
|
||||
background-color: #289DFF !important;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 13. 快捷选项样式 ========== */
|
||||
.custom-date-picker .el-picker-panel__shortcut {
|
||||
@ -219,6 +226,7 @@
|
||||
background-color: rgba(40, 157, 255, 0.2) !important;
|
||||
color: #289DFF !important;
|
||||
}
|
||||
.el-range__icon{
|
||||
color: #289DFF !important;
|
||||
|
||||
.el-range__icon {
|
||||
color: #289DFF !important;
|
||||
}
|
||||
@ -31,9 +31,9 @@ export const typeOptions = [
|
||||
// 管控措施选项
|
||||
export const controlMeasureOptions = [
|
||||
{ label: "全幅封闭", value: "全幅封闭" },
|
||||
{ label: "半幅封闭", value: "半幅封闭" },
|
||||
{ label: "正常通行", value: "正常通行" },
|
||||
{ label: "限制通行", value: "限制通行" },
|
||||
{ label: "半幅通行", value: "半幅通行" },
|
||||
{ label: "限速", value: "限速" },
|
||||
{ label: "告警阻拦", value: "告警阻拦" },
|
||||
];
|
||||
|
||||
// 风险等级选项
|
||||
@ -79,8 +79,8 @@ export const warningLevelOptions = [
|
||||
// 是否结束选项
|
||||
export const isEndedOptions = [
|
||||
{ label: "全部", value: "" },
|
||||
{ label: "是", value: "yes" },
|
||||
{ label: "否", value: "no" },
|
||||
{ label: "是", value: true },
|
||||
{ label: "否", value: false },
|
||||
];
|
||||
|
||||
// 行政区域选项(带全部)
|
||||
|
||||
@ -25,59 +25,12 @@
|
||||
<div class="corner corner-bottom-left"></div>
|
||||
<div class="corner corner-bottom-right"></div>
|
||||
<!-- 中心数据展示卡片 -->
|
||||
<div class="center-info-card-container">
|
||||
<!-- <div
|
||||
class="center-info-card"
|
||||
@click="openDialog('tongnanResponsible')"
|
||||
v-if="showCenterCard.type === 'first'"
|
||||
>
|
||||
<div class="card-title">潼南</div>
|
||||
<div class="card-content">
|
||||
<div class="info-item clickable">
|
||||
<span class="info-label">人数</span>
|
||||
<span class="info-value">{{ showCenterCard.value }}</span>
|
||||
<span class="info-unit">人</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">项目</span>
|
||||
<span class="info-value">2</span>
|
||||
<span class="info-unit">处</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div
|
||||
class="center-info-card"
|
||||
v-if="
|
||||
showCenterCard.type === 'second' || showCenterCard.type === 'third'
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="card-title"
|
||||
@click="
|
||||
showCenterCard.type === 'second'
|
||||
? openDialog('tongnanTeam')
|
||||
: showCenterCard.type === 'third'
|
||||
? openDialog('responseSituation')
|
||||
: ''
|
||||
"
|
||||
>
|
||||
潼南
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="info-item">
|
||||
<span class="info-label">人数</span>
|
||||
<span class="info-value">{{ showCenterCard.value }}</span>
|
||||
<span class="info-unit">人</span>
|
||||
</div>
|
||||
<div class="info-item clickable">
|
||||
<span class="info-label">路段</span>
|
||||
<span class="info-value">117</span>
|
||||
<span class="info-unit">条</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<centerInfoCard
|
||||
:type="showCenterCard.type"
|
||||
:peopleCount="showCenterCard.value"
|
||||
roadCount="117"
|
||||
@click="handleCenterCardClick"
|
||||
/>
|
||||
|
||||
<div class="left">
|
||||
<left
|
||||
@ -88,7 +41,7 @@
|
||||
@openWarningSituation="openDialog('warningSituation')"
|
||||
@openResponseStatus="openDialog('responseStatus')"
|
||||
@openDispatchDistrict="openDialog('dispatchDistrict')"
|
||||
@showCenterCard="(item) => (showCenterCard = item)"
|
||||
@showCenterCard="(item) => handleCenterCardClick(item)"
|
||||
></left>
|
||||
</div>
|
||||
<div class="right">
|
||||
@ -102,150 +55,163 @@
|
||||
<div class="center">
|
||||
<!-- 地图底层 -->
|
||||
<div class="map-layer">
|
||||
<ChongqingMap ref="chongqingMapRef" :activeIndex="activeIndex" :dateRange="dateRange" />
|
||||
<ChongqingMap
|
||||
ref="chongqingMapRef"
|
||||
:activeIndex="activeIndex"
|
||||
:dateRange="dateRange"
|
||||
@districtClick="handleDistrictClick"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 地图遮罩层 -->
|
||||
<div class="map-mask" aria-hidden="true"></div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<bottom @changeActiveIndex="changeActiveIndex" @clearMapMarkers="clearMapMarkers"></bottom>
|
||||
<bottom
|
||||
@changeActiveIndex="changeActiveIndex"
|
||||
@clearMapMarkers="clearMapMarkers"
|
||||
></bottom>
|
||||
</div>
|
||||
<top class="top" @openAIResult="openDialog('aiWarningResult')" @dateRangeChange="handleDateRangeChange"></top>
|
||||
<top
|
||||
class="top"
|
||||
@openAIResult="openDialog('aiWarningResult')"
|
||||
@dateRangeChange="handleDateRangeChange"
|
||||
></top>
|
||||
<div>
|
||||
<!-- 农村公路对话框 -->
|
||||
<responseSituationDiaLog
|
||||
v-model:visible="dialogVisible.responseSituation"
|
||||
@close="closeDialog('responseSituation')"
|
||||
/>
|
||||
|
||||
<!-- 响应情况对话框 -->
|
||||
<responseSituationDiaLog
|
||||
v-model:visible="dialogVisible.responseSituation"
|
||||
@close="closeDialog('responseSituation')"
|
||||
/>
|
||||
<!-- 预警信息对话框 -->
|
||||
<warningInfoDialog
|
||||
v-model:visible="dialogVisible.warningInfo"
|
||||
@close="closeDialog('warningInfo')"
|
||||
@responseStatus="openDialog('responseStatus')"
|
||||
/>
|
||||
|
||||
<!-- 预警信息对话框 -->
|
||||
<warningInfoDialog
|
||||
v-model:visible="dialogVisible.warningInfo"
|
||||
@close="closeDialog('warningInfo')"
|
||||
@responseStatus="openDialog('responseStatus')"
|
||||
/>
|
||||
<!-- 事件详情对话框 -->
|
||||
<eventDetailDialog
|
||||
v-model:visible="dialogVisible.eventDetail"
|
||||
@close="closeDialog('eventDetail')"
|
||||
/>
|
||||
|
||||
<!-- 事件详情对话框 -->
|
||||
<eventDetailDialog
|
||||
v-model:visible="dialogVisible.eventDetail"
|
||||
@close="closeDialog('eventDetail')"
|
||||
/>
|
||||
<!-- 确认对话框 -->
|
||||
<confirmDialog
|
||||
v-model:visible="dialogVisible.confirm"
|
||||
:title="confirmConfig.title"
|
||||
:message="confirmConfig.message"
|
||||
:confirm-text="confirmConfig.confirmText"
|
||||
:cancel-text="confirmConfig.cancelText"
|
||||
@confirm="closeDialog('confirm')"
|
||||
@cancel="closeDialog('confirm')"
|
||||
/>
|
||||
|
||||
<!-- 确认对话框 -->
|
||||
<confirmDialog
|
||||
v-model:visible="dialogVisible.confirm"
|
||||
:title="confirmConfig.title"
|
||||
:message="confirmConfig.message"
|
||||
:confirm-text="confirmConfig.confirmText"
|
||||
:cancel-text="confirmConfig.cancelText"
|
||||
@confirm="closeDialog('confirm')"
|
||||
@cancel="closeDialog('confirm')"
|
||||
/>
|
||||
<!-- 风险点详情对话框 -->
|
||||
<riskPointDetailDialog
|
||||
v-model:visible="dialogVisible.riskPointDetail"
|
||||
@close="closeDialog('riskPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 风险点详情对话框 -->
|
||||
<riskPointDetailDialog
|
||||
v-model:visible="dialogVisible.riskPointDetail"
|
||||
@close="closeDialog('riskPointDetail')"
|
||||
/>
|
||||
<!-- 影响点情况对话框 -->
|
||||
<impactPointDialog
|
||||
v-model:visible="dialogVisible.impactPoint"
|
||||
@close="closeDialog('impactPoint')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 影响点情况对话框 -->
|
||||
<impactPointDialog
|
||||
v-model:visible="dialogVisible.impactPoint"
|
||||
@close="closeDialog('impactPoint')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
<!-- 影响点详情对话框 -->
|
||||
<impactPointDetailDialog
|
||||
v-model:visible="dialogVisible.impactPointDetail"
|
||||
@close="closeDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 影响点详情对话框 -->
|
||||
<impactPointDetailDialog
|
||||
v-model:visible="dialogVisible.impactPointDetail"
|
||||
@close="closeDialog('impactPointDetail')"
|
||||
/>
|
||||
<!-- 响应点详情对话框 -->
|
||||
<responsePointDetailDialog
|
||||
v-model:visible="dialogVisible.responsePointDetail"
|
||||
@close="closeDialog('responsePointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 响应点详情对话框 -->
|
||||
<responsePointDetailDialog
|
||||
v-model:visible="dialogVisible.responsePointDetail"
|
||||
@close="closeDialog('responsePointDetail')"
|
||||
/>
|
||||
<!-- 响应点信息对话框 -->
|
||||
<responsePointInfoDialog
|
||||
v-model:visible="dialogVisible.responsePointInfo"
|
||||
@close="closeDialog('responsePointInfo')"
|
||||
/>
|
||||
|
||||
<!-- 响应点信息对话框 -->
|
||||
<responsePointInfoDialog
|
||||
v-model:visible="dialogVisible.responsePointInfo"
|
||||
@close="closeDialog('responsePointInfo')"
|
||||
/>
|
||||
<!-- 响应状态对话框 -->
|
||||
<responseStatusDialog
|
||||
v-model:visible="dialogVisible.responseStatus"
|
||||
@close="closeDialog('responseStatus')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
|
||||
<!-- 响应状态对话框 -->
|
||||
<responseStatusDialog
|
||||
v-model:visible="dialogVisible.responseStatus"
|
||||
@close="closeDialog('responseStatus')"
|
||||
@detail="openDialog('impactPointDetail')"
|
||||
/>
|
||||
<!-- AI预警处理结果对话框 -->
|
||||
<aiWarningResultDialog
|
||||
v-model:visible="dialogVisible.aiWarningResult"
|
||||
@close="closeDialog('aiWarningResult')"
|
||||
/>
|
||||
|
||||
<!-- AI预警处理结果对话框 -->
|
||||
<aiWarningResultDialog
|
||||
v-model:visible="dialogVisible.aiWarningResult"
|
||||
@close="closeDialog('aiWarningResult')"
|
||||
/>
|
||||
<!-- 潼南基本信息对话框 -->
|
||||
<tongnanInfoDialog
|
||||
v-model:visible="dialogVisible.tongnanInfo"
|
||||
@close="closeDialog('tongnanInfo')"
|
||||
@call="openDialog('confirm')"
|
||||
/>
|
||||
|
||||
<!-- 潼南基本信息对话框 -->
|
||||
<tongnanInfoDialog
|
||||
v-model:visible="dialogVisible.tongnanInfo"
|
||||
@close="closeDialog('tongnanInfo')"
|
||||
@call="openDialog('confirm')"
|
||||
/>
|
||||
<!-- 项目对话框 -->
|
||||
<tongnanResponsibleDialog
|
||||
v-model:visible="dialogVisible.tongnanResponsible"
|
||||
@close="closeDialog('tongnanResponsible')"
|
||||
@detail="openDialog('tongnanInfo')"
|
||||
/>
|
||||
|
||||
<!-- 潼南建设项目责任人明细对话框 -->
|
||||
<tongnanResponsibleDialog
|
||||
v-model:visible="dialogVisible.tongnanResponsible"
|
||||
@close="closeDialog('tongnanResponsible')"
|
||||
@detail="openDialog('tongnanInfo')"
|
||||
/>
|
||||
<!-- 抢通情况对话框 -->
|
||||
<clearanceSituationDialog
|
||||
v-model:visible="dialogVisible.clearanceSituation"
|
||||
@close="closeDialog('clearanceSituation')"
|
||||
@detail="openDialog('eventDetail')"
|
||||
/>
|
||||
|
||||
<!-- 抢通情况对话框 -->
|
||||
<clearanceSituationDialog
|
||||
v-model:visible="dialogVisible.clearanceSituation"
|
||||
@close="closeDialog('clearanceSituation')"
|
||||
@detail="openDialog('eventDetail')"
|
||||
/>
|
||||
<!-- 管控情况对话框 -->
|
||||
<controlSituationDialog
|
||||
v-model:visible="dialogVisible.controlSituation"
|
||||
@close="closeDialog('controlSituation')"
|
||||
/>
|
||||
|
||||
<!-- 管控情况对话框 -->
|
||||
<controlSituationDialog
|
||||
v-model:visible="dialogVisible.controlSituation"
|
||||
@close="closeDialog('controlSituation')"
|
||||
/>
|
||||
<!-- 调度详情对话框 -->
|
||||
<dispatchDetailDialog
|
||||
v-model:visible="dialogVisible.dispatchDetail"
|
||||
@close="closeDialog('dispatchDetail')"
|
||||
/>
|
||||
|
||||
<!-- 调度详情对话框 -->
|
||||
<dispatchDetailDialog
|
||||
v-model:visible="dialogVisible.dispatchDetail"
|
||||
@close="closeDialog('dispatchDetail')"
|
||||
/>
|
||||
<!-- 调度区县情况对话框 -->
|
||||
<dispatchDistrictDialog
|
||||
v-model:visible="dialogVisible.dispatchDistrict"
|
||||
@close="closeDialog('dispatchDistrict')"
|
||||
@dispatchClick="openDialog('dispatchDetail')"
|
||||
/>
|
||||
|
||||
<!-- 调度区县情况对话框 -->
|
||||
<dispatchDistrictDialog
|
||||
v-model:visible="dialogVisible.dispatchDistrict"
|
||||
@close="closeDialog('dispatchDistrict')"
|
||||
@dispatchClick="openDialog('dispatchDetail')"
|
||||
/>
|
||||
<!-- 国省道对话框 -->
|
||||
<tongnanTeamDialog
|
||||
v-model:visible="dialogVisible.tongnanTeam"
|
||||
@close="closeDialog('tongnanTeam')"
|
||||
@view="openDialog('tongnanInfo')"
|
||||
/>
|
||||
|
||||
<!-- 潼南护路团队成员对话框 -->
|
||||
<tongnanTeamDialog
|
||||
v-model:visible="dialogVisible.tongnanTeam"
|
||||
@close="closeDialog('tongnanTeam')"
|
||||
@view="openDialog('tongnanInfo')"
|
||||
/>
|
||||
<!-- 预警情况对话框 -->
|
||||
<warningSituationDialog
|
||||
v-model:visible="dialogVisible.warningSituation"
|
||||
@close="closeDialog('warningSituation')"
|
||||
@impactClick="openDialog('impactPoint')"
|
||||
/>
|
||||
|
||||
<!-- 预警情况对话框 -->
|
||||
<warningSituationDialog
|
||||
v-model:visible="dialogVisible.warningSituation"
|
||||
@close="closeDialog('warningSituation')"
|
||||
@impactClick="openDialog('impactPoint')"
|
||||
/>
|
||||
|
||||
<!-- 隧道信息对话框 -->
|
||||
<tunnelInfoDialog
|
||||
v-model:visible="dialogVisible.tunnelInfo"
|
||||
@close="closeDialog('tunnelInfo')"
|
||||
/>
|
||||
<!-- 隧道信息对话框 -->
|
||||
<tunnelInfoDialog
|
||||
v-model:visible="dialogVisible.tunnelInfo"
|
||||
@close="closeDialog('tunnelInfo')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -280,9 +246,10 @@ import dispatchDistrictDialog from "./Dialog/dispatchDistrictDialog.vue";
|
||||
import tongnanTeamDialog from "./Dialog/tongnanTeamDialog.vue";
|
||||
import warningSituationDialog from "./Dialog/warningSituationDialog.vue";
|
||||
import tunnelInfoDialog from "./Dialog/tunnelInfoDialog.vue";
|
||||
import centerInfoCard from "./Dialog/centerInfoCard.vue";
|
||||
|
||||
import './component/el-select.scss'
|
||||
import './component/date-picker-theme.scss'
|
||||
import "./component/el-select.scss";
|
||||
import "./component/date-picker-theme.scss";
|
||||
|
||||
// 弹窗显示状态
|
||||
const dialogVisible = ref({
|
||||
@ -304,8 +271,8 @@ const dialogVisible = ref({
|
||||
dispatchDetail: false,
|
||||
dispatchDistrict: false,
|
||||
tongnanTeam: false,
|
||||
warningSituation: false,
|
||||
tunnelInfo: false
|
||||
warningSituation: false,
|
||||
tunnelInfo: false,
|
||||
});
|
||||
const activeIndex = ref(0);
|
||||
|
||||
@ -376,10 +343,67 @@ const openConfirm = (config) => {
|
||||
confirmConfig.value = { ...confirmConfig.value, ...config };
|
||||
dialogVisible.value.confirm = true;
|
||||
};
|
||||
|
||||
// 中心信息卡片显示状态
|
||||
const showCenterCard = ref(false);
|
||||
|
||||
// 处理区县点击
|
||||
const handleDistrictClick = (item) => {
|
||||
console.log("区县点击:", item.data);
|
||||
if (item.data.roadType == "national") {
|
||||
// 国省道
|
||||
openDialog("tongnanTeam");
|
||||
} else if (item.data.roadType == "rural") {
|
||||
openDialog("responseSituation");
|
||||
} else if (item.data.type == "project" && item.data.roadType == "-") {
|
||||
// 项目
|
||||
openDialog("tongnanResponsible");
|
||||
}
|
||||
};
|
||||
|
||||
// 处理中心卡片点击
|
||||
const handleCenterCardClick = (item) => {
|
||||
console.log("中心卡片点击:", item);
|
||||
|
||||
// 调用地图组件的方法打开中心信息卡片弹窗
|
||||
if (chongqingMapRef.value && item.data) {
|
||||
const cardData = {
|
||||
title: getCardTitleByType(item.type),
|
||||
dataList: item.data,
|
||||
};
|
||||
chongqingMapRef.value.openCenterCard(cardData);
|
||||
|
||||
// 如果数据中包含区县信息,定位到第一个区县
|
||||
if (
|
||||
item.data.length > 0 &&
|
||||
(item.data[0].countyName || item.data[0].name)
|
||||
) {
|
||||
const firstCounty = item.data[0].countyName || item.data[0].name;
|
||||
chongqingMapRef.value.locateToDistrict(firstCounty);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 根据类型获取卡片标题
|
||||
const getCardTitleByType = (type) => {
|
||||
const titleMap = {
|
||||
first: "国省道调度",
|
||||
second: "农村公路调度",
|
||||
third: "建设工程调度",
|
||||
};
|
||||
return titleMap[type] || "调度统计";
|
||||
};
|
||||
const handleCenterCardClickType = (item) => {
|
||||
console.log(item.data);
|
||||
showCenterCard.value = true;
|
||||
// if (item.type === "second") {
|
||||
// openDialog("tongnanTeam");
|
||||
// } else if (item.type === "third") {
|
||||
// openDialog("responseSituation");
|
||||
// } else if (item.type === "first") {
|
||||
// openDialog("warningSituation");
|
||||
// }
|
||||
};
|
||||
|
||||
// 兄弟组件通信机制
|
||||
const refreshLeftData = ref(null);
|
||||
|
||||
@ -396,8 +420,8 @@ const triggerRefreshLeftData = () => {
|
||||
};
|
||||
|
||||
// 提供通信机制给子组件
|
||||
provide('setRefreshLeftData', setRefreshLeftData);
|
||||
provide('triggerRefreshLeftData', triggerRefreshLeftData);
|
||||
provide("setRefreshLeftData", setRefreshLeftData);
|
||||
provide("triggerRefreshLeftData", triggerRefreshLeftData);
|
||||
|
||||
// ==================== 地图状态管理 ====================
|
||||
|
||||
@ -483,7 +507,7 @@ onMounted(() => {
|
||||
top: vw(60);
|
||||
width: 25%;
|
||||
height: calc(100% - #{vw(60)});
|
||||
z-index: 2;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.right {
|
||||
@ -492,7 +516,7 @@ onMounted(() => {
|
||||
top: vw(60);
|
||||
width: 25%;
|
||||
height: calc(100% - #{vw(60)});
|
||||
z-index: 2;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
@ -508,7 +532,7 @@ onMounted(() => {
|
||||
top: vw(100);
|
||||
left: 25%;
|
||||
width: 50%;
|
||||
z-index: 2;
|
||||
z-index: 4;
|
||||
// height: 15%;
|
||||
// background-color: #15293B;
|
||||
}
|
||||
@ -519,7 +543,7 @@ onMounted(() => {
|
||||
// left: 25%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 地图底层 - 填满整个容器 */
|
||||
@ -579,91 +603,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.center-info-card-container {
|
||||
position: absolute;
|
||||
top: 30%;
|
||||
left: 32%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: vw(200);
|
||||
min-width: 200px;
|
||||
z-index: 200;
|
||||
}
|
||||
// 中心数据展示卡片
|
||||
.center-info-card {
|
||||
background: rgba(64, 169, 255, 0.2);
|
||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
||||
z-index: 50;
|
||||
box-shadow:
|
||||
0 4px 20px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
margin-bottom: vw(10);
|
||||
|
||||
// &:hover {
|
||||
// border-color: rgba(64, 169, 255, 0.6);
|
||||
// box-shadow: 0 6px 30px rgba(64, 169, 255, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
// transform: translate(-50%, -52%);
|
||||
// }
|
||||
|
||||
.card-title {
|
||||
font-size: vw(16);
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: vw(12);
|
||||
background: rgba(64, 169, 255, 0.8);
|
||||
padding: vw(16) vw(20);
|
||||
border-bottom: 1px solid rgba(64, 169, 255, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 0 vw(20) vw(16) vw(20);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: vw(4);
|
||||
|
||||
.info-label {
|
||||
font-size: vw(13);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: vw(24);
|
||||
font-weight: 700;
|
||||
color: #40a9ff;
|
||||
text-shadow: 0 0 10px rgba(64, 169, 255, 0.5);
|
||||
}
|
||||
|
||||
.info-unit {
|
||||
font-size: vw(14);
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
.info-value {
|
||||
color: #69c0ff;
|
||||
text-shadow: 0 0 15px rgba(105, 192, 255, 0.8);
|
||||
}
|
||||
|
||||
.info-label,
|
||||
.info-unit {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 下拉选项浮窗
|
||||
.el-popper {
|
||||
// 下拉选项
|
||||
|
||||
@ -125,7 +125,8 @@
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
size="small"
|
||||
popper-class="dark-date-picker"
|
||||
popper-class="custom-date-picker"
|
||||
:teleported="false"
|
||||
:prefix-icon="Calendar"
|
||||
@change="handleDateChange"
|
||||
/>
|
||||
@ -222,6 +223,7 @@ const init = () => {
|
||||
roadTypeLoad();
|
||||
districtLoadLoad();
|
||||
dispatchLoadLoad();
|
||||
scheduleStatisticsByCountyLoad();
|
||||
loadData();
|
||||
loadBarChartData();
|
||||
};
|
||||
@ -263,16 +265,19 @@ const handleDispatchCardClick = (item) => {
|
||||
emit("showCenterCard", {
|
||||
type: "second",
|
||||
value: item.value,
|
||||
data: nationalarr.value,
|
||||
});
|
||||
} else if (item.label === dispatchList.value[1].label) {
|
||||
emit("showCenterCard", {
|
||||
type: "third",
|
||||
value: item.value,
|
||||
data: ruralarr.value,
|
||||
});
|
||||
} else if (item.label === dispatchList.value[2].label) {
|
||||
emit("showCenterCard", {
|
||||
type: "first",
|
||||
value: item.value,
|
||||
data: projectarr.value,
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -401,6 +406,100 @@ const districtLoadLoad = async () => {
|
||||
}
|
||||
};
|
||||
const roadTypeData = ref([]);
|
||||
|
||||
// 调度统计区县数据
|
||||
const projectarr = ref([]);
|
||||
const nationalarr = ref([]);
|
||||
const ruralarr = ref([]);
|
||||
const scheduleStatisticsByCountyLoad = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/weather-warning/schedule-statistics/_by_county",
|
||||
method: "GET",
|
||||
});
|
||||
console.log("调度统计区县数据:", res);
|
||||
if (res.code == "00000") {
|
||||
const data = res.data;
|
||||
if (data) {
|
||||
data.forEach((item) => {
|
||||
if (item.countyName != "测试区县") {
|
||||
if (item.type == "project") {
|
||||
projectarr.value.push(item);
|
||||
} else if (item.roadType == "national") {
|
||||
nationalarr.value.push(item);
|
||||
} else if (item.roadType == "rural") {
|
||||
ruralarr.value.push(item);
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(projectarr.value);
|
||||
console.log(nationalarr.value);
|
||||
console.log(ruralarr.value);
|
||||
|
||||
// 合并渝北区和江北区为两江新区
|
||||
const mergeLiangjiangNewArea = (arr) => {
|
||||
const yubeiItems = arr.filter(item => item.countyName === "渝北区");
|
||||
const jiangbeiItems = arr.filter(item => item.countyName === "江北区");
|
||||
|
||||
if (yubeiItems.length > 0 || jiangbeiItems.length > 0) {
|
||||
// 计算合并后的数据
|
||||
const mergedItem = {
|
||||
countyName: "两江新区",
|
||||
countyId: yubeiItems[0]?.countyId || jiangbeiItems[0]?.countyId || "",
|
||||
type: yubeiItems[0]?.type || jiangbeiItems[0]?.type || "",
|
||||
roadType: yubeiItems[0]?.roadType || jiangbeiItems[0]?.roadType || "",
|
||||
// 数值字段累加
|
||||
noticeCount: 0,
|
||||
replyCount: 0,
|
||||
population: 0,
|
||||
entityCount: 0,
|
||||
};
|
||||
|
||||
// 累加渝北区数据
|
||||
yubeiItems.forEach(item => {
|
||||
mergedItem.noticeCount += item.noticeCount || 0;
|
||||
mergedItem.replyCount += item.replyCount || 0;
|
||||
mergedItem.population += item.population || 0;
|
||||
mergedItem.entityCount += item.entityCount || 0;
|
||||
});
|
||||
|
||||
// 累加江北区数据
|
||||
jiangbeiItems.forEach(item => {
|
||||
mergedItem.noticeCount += item.noticeCount || 0;
|
||||
mergedItem.replyCount += item.replyCount || 0;
|
||||
mergedItem.population += item.population || 0;
|
||||
mergedItem.entityCount += item.entityCount || 0;
|
||||
});
|
||||
|
||||
// 移除渝北区和江北区的数据,添加合并后的两江新区数据
|
||||
const filteredArr = arr.filter(item =>
|
||||
item.countyName !== "渝北区" && item.countyName !== "江北区"
|
||||
);
|
||||
filteredArr.push(mergedItem);
|
||||
return filteredArr;
|
||||
}
|
||||
|
||||
return arr;
|
||||
};
|
||||
|
||||
// 对三个数组分别进行合并处理
|
||||
projectarr.value = mergeLiangjiangNewArea(projectarr.value);
|
||||
nationalarr.value = mergeLiangjiangNewArea(nationalarr.value);
|
||||
ruralarr.value = mergeLiangjiangNewArea(ruralarr.value);
|
||||
|
||||
// 过滤出前15个项目、10个全国、5个农村
|
||||
projectarr.value = projectarr.value.filter((item, index) => index < 15);
|
||||
nationalarr.value = nationalarr.value.filter(
|
||||
(item, index) => index < 10,
|
||||
);
|
||||
ruralarr.value = ruralarr.value.filter((item, index) => index < 5);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("加载调度统计区县数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 公路类型数据
|
||||
const roadTypeLoad = async () => {
|
||||
try {
|
||||
@ -491,15 +590,19 @@ const loadBarChartData = async () => {
|
||||
const name = nameMap[item.name] || item.name;
|
||||
return { ...item, name };
|
||||
});
|
||||
|
||||
// 将路段放到数组第一个
|
||||
const roadIndex = convertedData.findIndex((item) => item.name === "路段");
|
||||
if (roadIndex > 0) {
|
||||
const roadItem = convertedData.splice(roadIndex, 1)[0];
|
||||
convertedData.unshift(roadItem);
|
||||
}
|
||||
|
||||
impactData.value = convertedData;
|
||||
convertedData.forEach((item) => {
|
||||
if (item.name == "路段") {
|
||||
impactData.value[0].count = item.count || 0;
|
||||
} else if (item.name == "桥梁") {
|
||||
impactData.value[1].count = item.count || 0;
|
||||
} else if (item.name == "隧道") {
|
||||
impactData.value[2].count = item.count || 0;
|
||||
} else if (item.name == "边坡") {
|
||||
impactData.value[3].count = item.count || 0;
|
||||
} else if (item.name == "项目") {
|
||||
impactData.value[4].count = item.count || 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@ -125,7 +125,8 @@
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
size="small"
|
||||
popper-class="dark-date-picker"
|
||||
popper-class="custom-date-picker"
|
||||
:teleported="false"
|
||||
:prefix-icon="Calendar"
|
||||
/>
|
||||
</div>
|
||||
@ -226,6 +227,9 @@ const emit = defineEmits([
|
||||
onMounted(() => {
|
||||
getYhYjllList();
|
||||
getYhYjllListMaterials();
|
||||
getControlStats();
|
||||
getRescueInputStats();
|
||||
getDisasterStats();
|
||||
});
|
||||
|
||||
// 获取应急力量列表数据
|
||||
@ -312,6 +316,168 @@ const getYhYjllListMaterials = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 获取管控统计数据
|
||||
const getControlStats = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/sm-event/dashboard/control-stats",
|
||||
method: "GET",
|
||||
});
|
||||
console.log("管控统计数据:", res);
|
||||
if (res.code == "00000" && res.data) {
|
||||
const data = res.data;
|
||||
// 更新controlData1数组的value值
|
||||
controlData1.value.forEach((item) => {
|
||||
if (item.label === "封闭管控数") {
|
||||
item.value = data.fullClosureCount || "0";
|
||||
} else if (item.label === "半幅通行数") {
|
||||
item.value = data.halfClosureCount || "0";
|
||||
} else if (item.label === "限速(限车型)数") {
|
||||
item.value = data.speedLimitCount || "0";
|
||||
} else if (item.label === "告警阻拦处数") {
|
||||
item.value = data.warningBlockCount || "0";
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取管控统计数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取抢险投入统计数据
|
||||
const getRescueInputStats = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/sm-event/dashboard/rescue-input-stats",
|
||||
method: "GET",
|
||||
});
|
||||
console.log("抢险投入统计数据:", res);
|
||||
if (res.code == "00000" && res.data) {
|
||||
const data = res.data;
|
||||
// 更新rescueData数组的value值
|
||||
rescueData.value.forEach((item) => {
|
||||
if (item.label === "本轮出动人次") {
|
||||
item.value = data.investedManpower || "0";
|
||||
item.unit = "人";
|
||||
if (item.value > 10000) {
|
||||
item.value = (item.value / 10000).toFixed(2);
|
||||
item.unit = "万人";
|
||||
}
|
||||
} else if (item.label === "本轮出动设备") {
|
||||
item.value = data.investedMachinery || "0";
|
||||
item.unit = "台";
|
||||
if (item.value > 10000) {
|
||||
item.value = (item.value / 10000).toFixed(2);
|
||||
item.unit = "万台";
|
||||
}
|
||||
} else if (item.label === "清理塌方") {
|
||||
// 将立方米转换为万立方米
|
||||
item.value = data.clearedLandslide.toFixed(2) || 0;
|
||||
item.unit = "立方米";
|
||||
if (item.value > 10000) {
|
||||
item.value = (item.value / 10000).toFixed(2);
|
||||
item.unit = "万立方米";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取抢险投入统计数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取灾害统计数据
|
||||
const getDisasterStats = async () => {
|
||||
try {
|
||||
const res = await request({
|
||||
url: "/snow-ops-platform/sm-event/dashboard/disaster-stats",
|
||||
method: "GET",
|
||||
});
|
||||
console.log("灾害统计数据:", res);
|
||||
if (res.code == "00000" && res.data) {
|
||||
const data = res.data;
|
||||
// 更新blockData数组的value值
|
||||
blockData.value.forEach((item) => {
|
||||
if (item.label === "今日新增阻断数") {
|
||||
item.current = data.todayNormalCount || "0";
|
||||
item.total = data.todayTotalCount || "0";
|
||||
} else if (item.label === "本轮累计阻断数") {
|
||||
item.current = data.roundNormalCount || "0";
|
||||
item.total = data.roundTotalCount || "0";
|
||||
}
|
||||
});
|
||||
|
||||
// 更新deathData的value值
|
||||
deathData.value.value = data.roundDeadCount || "0";
|
||||
|
||||
// 更新damageData数组的value值
|
||||
damageData.value.forEach((item) => {
|
||||
if (item.label === "本轮塌方量") {
|
||||
data.roundLandslideVolume = data.roundLandslideVolume.toFixed(2);
|
||||
if (data.roundLandslideVolume > 10000) {
|
||||
item.value = (data.roundLandslideVolume / 10000).toFixed(2) || "0";
|
||||
item.unit = "万立方米";
|
||||
} else {
|
||||
item.value = data.roundLandslideVolume || "0";
|
||||
item.unit = "立方米";
|
||||
}
|
||||
} else if (item.label === "汛期塌方量") {
|
||||
data.floodSeasonLandslideVolume =
|
||||
data.floodSeasonLandslideVolume.toFixed(2);
|
||||
if (data.floodSeasonLandslideVolume > 10000) {
|
||||
item.value =
|
||||
(data.floodSeasonLandslideVolume / 10000).toFixed(2) || "0";
|
||||
item.unit = "万立方米";
|
||||
} else {
|
||||
item.value = data.floodSeasonLandslideVolume || "0";
|
||||
item.unit = "立方米";
|
||||
}
|
||||
} else if (item.label === "当年塌方量") {
|
||||
data.yearLandslideVolume = data.yearLandslideVolume.toFixed(2);
|
||||
if (data.yearLandslideVolume > 10000) {
|
||||
item.value = (data.yearLandslideVolume / 10000).toFixed(2) || "0";
|
||||
item.unit = "万立方米";
|
||||
} else {
|
||||
item.value = data.yearLandslideVolume || "0";
|
||||
item.unit = "立方米";
|
||||
}
|
||||
} else if (item.label === "本轮已损失") {
|
||||
data.roundTotalLossAmount = data.roundTotalLossAmount.toFixed(2);
|
||||
if (data.roundTotalLossAmount > 10000) {
|
||||
item.value = (data.roundTotalLossAmount / 10000).toFixed(2) || "0";
|
||||
item.unit = "亿元";
|
||||
} else {
|
||||
item.value = data.roundTotalLossAmount || "0";
|
||||
item.unit = "万元";
|
||||
}
|
||||
} else if (item.label === "汛期已损失") {
|
||||
data.floodSeasonTotalLossAmount =
|
||||
data.floodSeasonTotalLossAmount.toFixed(2);
|
||||
if (data.floodSeasonTotalLossAmount > 10000) {
|
||||
item.value =
|
||||
(data.floodSeasonTotalLossAmount / 10000).toFixed(2) || "0";
|
||||
item.unit = "亿元";
|
||||
} else {
|
||||
item.value = data.floodSeasonTotalLossAmount || "0";
|
||||
item.unit = "万元";
|
||||
}
|
||||
} else if (item.label === "当年已损失") {
|
||||
data.yearTotalLossAmount = data.yearTotalLossAmount.toFixed(2);
|
||||
if (data.yearTotalLossAmount > 10000) {
|
||||
item.value = (data.yearTotalLossAmount / 10000).toFixed(2) || "0";
|
||||
item.unit = "亿元";
|
||||
} else {
|
||||
item.value = data.yearTotalLossAmount || "0";
|
||||
item.unit = "万元";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取灾害统计数据失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 从字符串中提取数字并相加
|
||||
const extractAndSumNumbers = (value) => {
|
||||
// 如果是数字,直接返回
|
||||
@ -382,12 +548,12 @@ const handleResourceClick = (item) => {
|
||||
};
|
||||
|
||||
// 管控路段数据
|
||||
const controlData1 = [
|
||||
const controlData1 = ref([
|
||||
{ label: "封闭管控数", value: "40" },
|
||||
{ label: "半幅通行数", value: "40" },
|
||||
{ label: "限速(限车型)数", value: "24" },
|
||||
{ label: "告警阻拦处数", value: "32" },
|
||||
];
|
||||
]);
|
||||
const controlData2 = [
|
||||
{ label: "停工项目数", value: "30" },
|
||||
{ label: "关闭驻地数", value: "42" },
|
||||
@ -404,7 +570,7 @@ const patrolData = [
|
||||
];
|
||||
|
||||
// 抢险投入数据
|
||||
const rescueData = [
|
||||
const rescueData = ref([
|
||||
{
|
||||
label: "本轮出动人次",
|
||||
value: "22341",
|
||||
@ -422,30 +588,30 @@ const rescueData = [
|
||||
{
|
||||
label: "清理塌方",
|
||||
value: "1367",
|
||||
unit: "万立方米",
|
||||
unit: "立方米",
|
||||
iconClass: "icon-rescue-clear",
|
||||
img: icon13,
|
||||
},
|
||||
];
|
||||
]);
|
||||
|
||||
// 受灾情况 - 阻断数据
|
||||
const blockData = [
|
||||
const blockData = ref([
|
||||
{ label: "今日新增阻断数", current: "19", total: "23" },
|
||||
{ label: "本轮累计阻断数", current: "10", total: "23" },
|
||||
];
|
||||
]);
|
||||
|
||||
// 死亡人数
|
||||
const deathData = { label: "本轮因灾死亡人数", value: "5" };
|
||||
const deathData = ref({ label: "本轮因灾死亡人数", value: "5" });
|
||||
|
||||
// 灾害情况数据
|
||||
const damageData = [
|
||||
const damageData = ref([
|
||||
{ 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: "18", unit: "万元", class: "red" },
|
||||
{ label: "当年已损失", value: "350", unit: "万元", class: "red" },
|
||||
];
|
||||
]);
|
||||
|
||||
// 重大事件数
|
||||
const majorEvent = "0";
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
size="small"
|
||||
popper-class="dark-date-picker"
|
||||
popper-class="custom-date-picker"
|
||||
:teleported="false"
|
||||
:prefix-icon="Calendar"
|
||||
/>
|
||||
</div>
|
||||
@ -26,7 +27,7 @@ import { Calendar } from "@element-plus/icons-vue";
|
||||
const emit = defineEmits(["openAIResult", "dateRangeChange"]);
|
||||
|
||||
// 注入兄弟组件通信机制
|
||||
const triggerRefreshLeftData = inject('triggerRefreshLeftData');
|
||||
const triggerRefreshLeftData = inject("triggerRefreshLeftData");
|
||||
|
||||
const dateRange = ref([]);
|
||||
|
||||
@ -39,24 +40,28 @@ const setEndOfDay = (date) => {
|
||||
};
|
||||
|
||||
// 监听 dateRange 变化
|
||||
watch(dateRange, (newVal, oldVal) => {
|
||||
// 只有当值真正发生变化时才触发
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
console.log('dateRange 发生变化:', newVal);
|
||||
|
||||
// 如果有结束日期,将其设置为当天的23:59:59
|
||||
if (newVal && newVal.length === 2 && newVal[1]) {
|
||||
newVal[1] = setEndOfDay(newVal[1]);
|
||||
watch(
|
||||
dateRange,
|
||||
(newVal, oldVal) => {
|
||||
// 只有当值真正发生变化时才触发
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
console.log("dateRange 发生变化:", newVal);
|
||||
|
||||
// 如果有结束日期,将其设置为当天的23:59:59
|
||||
if (newVal && newVal.length === 2 && newVal[1]) {
|
||||
newVal[1] = setEndOfDay(newVal[1]);
|
||||
}
|
||||
|
||||
// 触发兄弟组件刷新
|
||||
if (triggerRefreshLeftData) {
|
||||
triggerRefreshLeftData();
|
||||
}
|
||||
// 向父组件传递时间范围
|
||||
emit("dateRangeChange", newVal);
|
||||
}
|
||||
|
||||
// 触发兄弟组件刷新
|
||||
if (triggerRefreshLeftData) {
|
||||
triggerRefreshLeftData();
|
||||
}
|
||||
// 向父组件传递时间范围
|
||||
emit("dateRangeChange", newVal);
|
||||
}
|
||||
}, { deep: true });
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
const handleAIClick = () => {
|
||||
emit("openAIResult");
|
||||
@ -89,6 +94,7 @@ const handleAIClick = () => {
|
||||
.filter-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: vw(20);
|
||||
min-height: 18px;
|
||||
gap: vw(8);
|
||||
@ -154,65 +160,4 @@ const handleAIClick = () => {
|
||||
min-height: 48px;
|
||||
cursor: pointer;
|
||||
}
|
||||
// 日期选择器下拉面板样式
|
||||
.dark-date-picker {
|
||||
background: rgba(21, 41, 59, 0.95) !important;
|
||||
border: 1px solid rgba(64, 169, 255, 0.3) !important;
|
||||
|
||||
.el-picker-panel__content {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.el-date-table {
|
||||
th {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
td {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
|
||||
&.prev-month,
|
||||
&.next-month {
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
|
||||
&.current:not(.disabled) {
|
||||
span {
|
||||
background: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
&.start-date,
|
||||
&.end-date {
|
||||
span {
|
||||
background: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
&.in-range {
|
||||
background: rgba(64, 169, 255, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-picker-panel__icon-btn {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
.el-date-picker__header-label {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
|
||||
&:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user