Compare commits
No commits in common. "82e10762a4b6f56dec0a7a17870c835ba3c54313" and "264501ee01d695494f3d62ecaf299436dfbec337" have entirely different histories.
82e10762a4
...
264501ee01
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<base-dialog
|
<base-dialog
|
||||||
v-model:visible="props.visible"
|
v-model:visible="props.visible"
|
||||||
:title="props.title"
|
title="涉灾隐患点情况"
|
||||||
:table-data="tableData"
|
:table-data="tableData"
|
||||||
:table-columns="tableColumns"
|
:table-columns="tableColumns"
|
||||||
:table-height="450"
|
:table-height="450"
|
||||||
@ -32,26 +32,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-item">
|
|
||||||
<span class="info-label">路线名称</span>
|
|
||||||
<span class="info-value">{{ hazardData.roadName }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">公路编号</span>
|
<span class="info-label">公路编号</span>
|
||||||
<span class="info-value">{{ hazardData.roadCode }}</span>
|
<span class="info-value">{{ hazardData.roadCode }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">位置</span>
|
<span class="info-label">位置</span>
|
||||||
<span class="info-value">{{ hazardData.location }}</span>
|
<span class="info-value">{{ hazardData.location }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
|
||||||
<span class="info-label">风险类型</span>
|
|
||||||
<span class="info-value">{{ hazardData.riskType }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 风险描述 -->
|
<!-- 风险描述 -->
|
||||||
<div class="info-block">
|
<div class="info-block">
|
||||||
<div class="block-title">风险描述</div>
|
<div class="block-title">风险描述</div>
|
||||||
@ -64,14 +55,8 @@
|
|||||||
<div class="block-content">{{ hazardData.measures }}</div>
|
<div class="block-content">{{ hazardData.measures }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 专家意见 - 仅涉灾隐患点显示 -->
|
|
||||||
<div v-if="!isRoadData && hazardData.expertOpinion" class="info-block">
|
|
||||||
<div class="block-title">专家意见</div>
|
|
||||||
<div class="block-content">{{ hazardData.expertOpinion }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 三级包保责任人 -->
|
<!-- 三级包保责任人 -->
|
||||||
<div class="info-block display jc_sb">
|
<div class="info-block">
|
||||||
<div class="block-title">三级包保责任人</div>
|
<div class="block-title">三级包保责任人</div>
|
||||||
<div class="responsibility-list">
|
<div class="responsibility-list">
|
||||||
<div class="responsibility-item">
|
<div class="responsibility-item">
|
||||||
@ -79,122 +64,59 @@
|
|||||||
<span class="responsibility-name">{{ hazardData.trafficDept.name }}</span>
|
<span class="responsibility-name">{{ hazardData.trafficDept.name }}</span>
|
||||||
<span class="responsibility-phone">{{ hazardData.trafficDept.phone }}</span>
|
<span class="responsibility-phone">{{ hazardData.trafficDept.phone }}</span>
|
||||||
<span class="responsibility-frequency">{{ hazardData.trafficDept.frequency }}</span>
|
<span class="responsibility-frequency">{{ hazardData.trafficDept.frequency }}</span>
|
||||||
<div class="action-btns">
|
|
||||||
<div class="action-btn" @click="handleVideo(hazardData.trafficDept)" title="视频">
|
|
||||||
<el-icon><VideoCamera /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleVoice(hazardData.trafficDept)" title="语音">
|
|
||||||
<el-icon><Microphone /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleCall(hazardData.trafficDept)" title="电话">
|
|
||||||
<el-icon><Phone /></el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="fs_12">半年巡查一次</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="responsibility-item">
|
<div class="responsibility-item">
|
||||||
<span class="responsibility-label">公路机构责任人:</span>
|
<span class="responsibility-label">公路机构责任人:</span>
|
||||||
<span class="responsibility-name">{{ hazardData.roadOrg.name }}</span>
|
<span class="responsibility-name">{{ hazardData.roadOrg.name }}</span>
|
||||||
<span class="responsibility-phone">{{ hazardData.roadOrg.phone }}</span>
|
<span class="responsibility-phone">{{ hazardData.roadOrg.phone }}</span>
|
||||||
<span class="responsibility-frequency">{{ hazardData.roadOrg.frequency }}</span>
|
<span class="responsibility-frequency">{{ hazardData.roadOrg.frequency }}</span>
|
||||||
<div class="action-btns">
|
|
||||||
<div class="action-btn" @click="handleVideo(hazardData.roadOrg)" title="视频">
|
|
||||||
<el-icon><VideoCamera /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleVoice(hazardData.roadOrg)" title="语音">
|
|
||||||
<el-icon><Microphone /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleCall(hazardData.roadOrg)" title="电话">
|
|
||||||
<el-icon><Phone /></el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="fs_12">每月巡查一次</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="responsibility-item">
|
<div class="responsibility-item">
|
||||||
<span class="responsibility-label">养护站责任人:</span>
|
<span class="responsibility-label">养护站责任人:</span>
|
||||||
<span class="responsibility-name">{{ hazardData.maintenance.name }}</span>
|
<span class="responsibility-name">{{ hazardData.maintenance.name }}</span>
|
||||||
<span class="responsibility-phone">{{ hazardData.maintenance.phone }}</span>
|
<span class="responsibility-phone">{{ hazardData.maintenance.phone }}</span>
|
||||||
<span class="responsibility-frequency">{{ hazardData.maintenance.frequency }}</span>
|
<span class="responsibility-frequency">{{ hazardData.maintenance.frequency }}</span>
|
||||||
<div class="action-btns">
|
|
||||||
<div class="action-btn" @click="handleVideo(hazardData.maintenance)" title="视频">
|
|
||||||
<el-icon><VideoCamera /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleVoice(hazardData.maintenance)" title="语音">
|
|
||||||
<el-icon><Microphone /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleCall(hazardData.maintenance)" title="电话">
|
|
||||||
<el-icon><Phone /></el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="fs_12">每周巡查一次</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 护路员 -->
|
<!-- 护路员 -->
|
||||||
<div class="info-block display jc_sb">
|
<div class="info-row simple-row">
|
||||||
<div class="block-title">护路员:</div>
|
<span class="row-label">护路员</span>
|
||||||
|
<span class="row-value name">{{ hazardData.roadKeeper.name }}</span>
|
||||||
|
<span class="row-value phone">{{ hazardData.roadKeeper.phone }}</span>
|
||||||
|
<span class="row-value frequency">{{ hazardData.roadKeeper.frequency }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="f1 display ai_center jc_end" style="gap: 8px">
|
<!-- 预警预报关 -->
|
||||||
<span class="responsibility-name">{{ hazardData.roadKeeper.name }}</span>
|
<div class="info-row simple-row">
|
||||||
<span class="responsibility-name" style="width: 100px;">{{ hazardData.roadKeeper.phone }}</span>
|
|
||||||
<span class="responsibility-frequency">{{ hazardData.roadKeeper.frequency }}</span>
|
|
||||||
<div class="action-btns">
|
|
||||||
<div class="action-btn" @click="handleVideo(hazardData.roadKeeper)" title="视频">
|
|
||||||
<el-icon><VideoCamera /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleVoice(hazardData.roadKeeper)" title="语音">
|
|
||||||
<el-icon><Microphone /></el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="action-btn" @click="handleCall(hazardData.roadKeeper)" title="电话">
|
|
||||||
<el-icon><Phone /></el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="fs_12">一周巡查两次</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 预警预报关 - 仅涉灾隐患点显示 -->
|
|
||||||
<div v-if="!isRoadData" class="info-row simple-row">
|
|
||||||
<span class="row-label">预警预报关</span>
|
<span class="row-label">预警预报关</span>
|
||||||
<!-- <span class="row-value">{{ hazardData.earlyWarning }}</span> -->
|
<span class="row-value">{{ hazardData.earlyWarning }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 线下巡查关 - 仅涉灾隐患点显示 -->
|
<!-- 线下巡查关 -->
|
||||||
<div v-if="!isRoadData" class="info-row simple-row">
|
<div class="info-row simple-row">
|
||||||
<span class="row-label">线下巡查关</span>
|
<span class="row-label">线下巡查关</span>
|
||||||
<!-- <span class="row-value">{{ hazardData.offlinePatrol }}</span> -->
|
<span class="row-value">{{ hazardData.offlinePatrol }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 交通管控关 - 仅涉灾隐患点显示 -->
|
<!-- 交通管控关 -->
|
||||||
<div v-if="!isRoadData" class="info-row simple-row">
|
<div class="info-row simple-row">
|
||||||
<span class="row-label">交通管控关</span>
|
<span class="row-label">交通管控关</span>
|
||||||
<!-- <span class="row-value">{{ hazardData.trafficControl }}</span> -->
|
<span class="row-value">{{ hazardData.trafficControl }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 力量预置关 - 仅涉灾隐患点显示 -->
|
<!-- 力量预置关 -->
|
||||||
<div v-if="!isRoadData" class="info-row simple-row">
|
<div class="info-row simple-row">
|
||||||
<span class="row-label">力量预置关</span>
|
<span class="row-label">力量预置关</span>
|
||||||
<!-- <span class="row-value">{{ hazardData.forcePreposition }}</span> -->
|
<span class="row-value">{{ hazardData.forcePreposition }}</span>
|
||||||
<el-icon class="location-icon"><Location /></el-icon>
|
<el-icon class="location-icon"><Location /></el-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 告警阻拦关 - 仅涉灾隐患点显示 -->
|
<!-- 告警阻拦关 -->
|
||||||
<div v-if="!isRoadData" class="info-row simple-row">
|
<div class="info-row simple-row">
|
||||||
<span class="row-label">告警阻拦关</span>
|
<span class="row-label">告警阻拦关</span>
|
||||||
<!-- <span class="row-value">{{ hazardData.alarmBlocking }}</span> -->
|
<span class="row-value">{{ hazardData.alarmBlocking }}</span>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 备注 - 仅涉灾隐患点显示 -->
|
|
||||||
<div v-if="!isRoadData && hazardData.remark" class="info-block display jc_sb">
|
|
||||||
<div class="block-title">备注</div>
|
|
||||||
<!-- <div class="block-content">{{ hazardData.remark }}</div> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 照片 - 路段数据展示 -->
|
|
||||||
<div v-if="isRoadData && hazardData.photos" class="info-block display jc_sb">
|
|
||||||
<div class="block-title">照片</div>
|
|
||||||
<div class="photo-list">
|
|
||||||
<img v-for="(photo, index) in hazardData.photos" :key="index" :src="photo" class="photo-item" @click="previewPhoto(photo)" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -202,10 +124,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, computed } from 'vue'
|
import { ref, watch } from 'vue';
|
||||||
import { Location, VideoCamera, Microphone, Phone } from '@element-plus/icons-vue'
|
import { Location } from '@element-plus/icons-vue';
|
||||||
import baseDialog from '../component/baseDialog.vue'
|
import baseDialog from '../component/baseDialog.vue';
|
||||||
import { openVideoConference } from '../component/index.js'
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
visible: {
|
visible: {
|
||||||
@ -216,25 +137,16 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
title: {
|
});
|
||||||
type: String,
|
|
||||||
default: '涉灾隐患点情况',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:visible', 'close', 'video', 'voice', 'call'])
|
const emit = defineEmits(['update:visible', 'close']);
|
||||||
|
|
||||||
// 判断是否为路段数据
|
|
||||||
const isRoadData = computed(() => {
|
|
||||||
return props.data?.dataType === 'road'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 表格列配置(为空,因为使用自定义内容)
|
// 表格列配置(为空,因为使用自定义内容)
|
||||||
const tableColumns = ref([])
|
const tableColumns = ref([]);
|
||||||
const tableData = ref([])
|
const tableData = ref([]);
|
||||||
const total = ref(0)
|
const total = ref(0);
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1);
|
||||||
const pageSize = ref(10)
|
const pageSize = ref(10);
|
||||||
|
|
||||||
// 隐患点数据(根据数据库字段映射)
|
// 隐患点数据(根据数据库字段映射)
|
||||||
const hazardData = ref({
|
const hazardData = ref({
|
||||||
@ -292,73 +204,44 @@ const hazardData = ref({
|
|||||||
// 坐标信息
|
// 坐标信息
|
||||||
longitude: '', // GL1_LON 经度
|
longitude: '', // GL1_LON 经度
|
||||||
latitude: '', // GL1_LAT 纬度
|
latitude: '', // GL1_LAT 纬度
|
||||||
|
});
|
||||||
// 照片信息(路段数据)
|
|
||||||
photos: [], // 照片列表
|
|
||||||
})
|
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
emit('update:visible', false)
|
emit('update:visible', false);
|
||||||
emit('close')
|
emit('close');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 分页操作
|
// 分页操作
|
||||||
const handleSizeChange = (val) => {
|
const handleSizeChange = val => {
|
||||||
pageSize.value = val
|
pageSize.value = val;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleCurrentChange = (val) => {
|
const handleCurrentChange = val => {
|
||||||
currentPage.value = val
|
currentPage.value = val;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 预览照片
|
|
||||||
const previewPhoto = (photo) => {
|
|
||||||
// 使用 Element Plus 的图片预览功能
|
|
||||||
const { preview } = require('element-plus')
|
|
||||||
preview(photo)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 视频通话
|
|
||||||
const handleVideo = (item) => {
|
|
||||||
console.log('视频通话:', item)
|
|
||||||
emit('video', {
|
|
||||||
...item,
|
|
||||||
id: hazardData.value.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 语音通话
|
|
||||||
const handleVoice = (item) => {
|
|
||||||
console.log('语音通话:', item)
|
|
||||||
emit('voice', item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拨打电话
|
|
||||||
const handleCall = (item) => {
|
|
||||||
console.log('拨打电话:', item)
|
|
||||||
emit('call', item)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听visible变化
|
// 监听visible变化
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
(newVal) => {
|
newVal => {
|
||||||
if (newVal && props.data) {
|
if (newVal && props.data) {
|
||||||
// 根据数据库字段映射数据
|
// 根据数据库字段映射数据
|
||||||
const data = props.data
|
const data = props.data;
|
||||||
hazardData.value = {
|
hazardData.value = {
|
||||||
// 基本信息
|
// 基本信息
|
||||||
district: data.GL1_QXMC || data.district || '',
|
district: data.GL1_QXMC || data.district || '',
|
||||||
riskLevel: data.GL1_FXDJ || data.riskLevel || '',
|
riskLevel: data.GL1_FXDJ || data.riskLevel || '',
|
||||||
roadCode: data.GL1_GLBH || data.roadCode || '',
|
roadCode: data.GL1_GLBH || data.roadCode || '',
|
||||||
roadName: data.GL1_GLMC || data.roadName || '',
|
roadName: data.GL1_GLMC || data.roadName || '',
|
||||||
location: data.GL1_QDZH && data.GL1_ZDZH ? `${data.GL1_QDZH}至${data.GL1_ZDZH}` : data.location || '',
|
location:
|
||||||
|
data.GL1_QDZH && data.GL1_ZDZH
|
||||||
|
? `${data.GL1_QDZH}至${data.GL1_ZDZH}`
|
||||||
|
: data.location || '',
|
||||||
riskDescription: data.GL1_FXMS || data.riskDescription || '',
|
riskDescription: data.GL1_FXMS || data.riskDescription || '',
|
||||||
riskType: data.GL1_FXLX || data.riskType || '',
|
riskType: data.GL1_FXLX || data.riskType || '',
|
||||||
measures: data.GL1_CQCS || data.measures || '',
|
measures: data.GL1_CQCS || data.measures || '',
|
||||||
isWithinRedLine: data.GL1_SFHXN || data.isWithinRedLine || '',
|
isWithinRedLine: data.GL1_SFHXN || data.isWithinRedLine || '',
|
||||||
id: data.GL1_ID || '',
|
|
||||||
|
|
||||||
// 三级包保责任人
|
// 三级包保责任人
|
||||||
trafficDept: {
|
trafficDept: {
|
||||||
@ -403,20 +286,17 @@ watch(
|
|||||||
// 坐标信息
|
// 坐标信息
|
||||||
longitude: data.GL1_LON || data.longitude || '',
|
longitude: data.GL1_LON || data.longitude || '',
|
||||||
latitude: data.GL1_LAT || data.latitude || '',
|
latitude: data.GL1_LAT || data.latitude || '',
|
||||||
|
};
|
||||||
// 照片信息(路段数据)
|
|
||||||
photos: data.photos || [],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
)
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.hazard-info-panel {
|
.hazard-info-panel {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
width: 650px;
|
width: 600px;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// 自定义滚动条样式
|
// 自定义滚动条样式
|
||||||
@ -462,6 +342,7 @@ watch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
.row-value {
|
.row-value {
|
||||||
|
flex: 1;
|
||||||
color: rgba(255, 255, 255, 0.9);
|
color: rgba(255, 255, 255, 0.9);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
||||||
@ -518,7 +399,6 @@ watch(
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
background: rgba(64, 169, 255, 0.05);
|
background: rgba(64, 169, 255, 0.05);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
// align-items: center;
|
|
||||||
|
|
||||||
.block-title {
|
.block-title {
|
||||||
color: rgba(255, 255, 255, 0.6);
|
color: rgba(255, 255, 255, 0.6);
|
||||||
@ -531,41 +411,6 @@ watch(
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
.responsibility-label {
|
|
||||||
color: rgba(255, 255, 255, 0.6);
|
|
||||||
font-size: 13px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.responsibility-name {
|
|
||||||
color: #40a9ff;
|
|
||||||
font-size: 14px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
// 按钮组
|
|
||||||
.action-btns {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #40a9ff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #40a9ff;
|
|
||||||
background: rgba(64, 169, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.responsibility-list {
|
.responsibility-list {
|
||||||
@ -582,101 +427,24 @@ watch(
|
|||||||
width: 140px;
|
width: 140px;
|
||||||
color: rgba(255, 255, 255, 0.6);
|
color: rgba(255, 255, 255, 0.6);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.responsibility-name {
|
.responsibility-name {
|
||||||
color: #40a9ff;
|
color: #40a9ff;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
flex-shrink: 0;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.responsibility-phone {
|
.responsibility-phone {
|
||||||
color: #40a9ff;
|
color: #40a9ff;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 100px;
|
width: 120px;
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.responsibility-frequency {
|
.responsibility-frequency {
|
||||||
color: rgba(255, 255, 255, 0.6);
|
color: rgba(255, 255, 255, 0.6);
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按钮组
|
|
||||||
.action-btns {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #40a9ff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #40a9ff;
|
|
||||||
background: rgba(64, 169, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 护路员行的按钮样式
|
|
||||||
.simple-row {
|
|
||||||
.action-btns {
|
|
||||||
display: flex;
|
|
||||||
margin-left: auto;
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: #40a9ff;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #40a9ff;
|
|
||||||
background: rgba(64, 169, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 照片列表样式
|
|
||||||
.photo-list {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.photo-item {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid rgba(64, 169, 255, 0.3);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-color: #40a9ff;
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,21 +68,6 @@
|
|||||||
<el-option v-for="option in regionOptions" :key="option.value" :label="option.label" :value="option.value" />
|
<el-option v-for="option in regionOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="filter-item">
|
|
||||||
<el-select
|
|
||||||
:teleported="false"
|
|
||||||
v-model="filterForm.roadType"
|
|
||||||
size="small"
|
|
||||||
placeholder="公路类型"
|
|
||||||
class="filter-select"
|
|
||||||
clearable
|
|
||||||
@change="handleFilterChange"
|
|
||||||
>
|
|
||||||
<el-option v-for="option in roadTypeOptions" :key="option.value" :label="option.label" :value="option.value" />
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="filter-item">
|
<div class="filter-item">
|
||||||
<el-button type="primary" class="search-btn" @click="handleSearch">查询</el-button>
|
<el-button type="primary" class="search-btn" @click="handleSearch">查询</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -194,7 +179,7 @@
|
|||||||
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
||||||
import { Close, ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
|
import { Close, ArrowLeft, ArrowRight } from '@element-plus/icons-vue'
|
||||||
import { request } from '@/utils/request'
|
import { request } from '@/utils/request'
|
||||||
import { pointTypeOptions, pointLevelOptions, regionOptions, roadTypeOptions } from '../component/index.js'
|
import { pointTypeOptions, pointLevelOptions, regionOptions } from '../component/index.js'
|
||||||
import baseDialog from '../component/baseDialog.vue'
|
import baseDialog from '../component/baseDialog.vue'
|
||||||
|
|
||||||
import respondedIcon from '../../../assets/xiangying/有回应@2x.png'
|
import respondedIcon from '../../../assets/xiangying/有回应@2x.png'
|
||||||
@ -228,7 +213,6 @@ const filterForm = ref({
|
|||||||
pointType: '',
|
pointType: '',
|
||||||
pointLevel: '',
|
pointLevel: '',
|
||||||
region: '',
|
region: '',
|
||||||
roadType: '',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 统一的表格列配置(桥梁、边坡、隧道、路段使用)
|
// 统一的表格列配置(桥梁、边坡、隧道、路段使用)
|
||||||
@ -497,7 +481,6 @@ const getTimeParams = () => {
|
|||||||
offset: (currentPage.value - 1) * pageSize.value,
|
offset: (currentPage.value - 1) * pageSize.value,
|
||||||
countyName: countyName || '',
|
countyName: countyName || '',
|
||||||
riskLevel: filterForm.value.pointLevel || '',
|
riskLevel: filterForm.value.pointLevel || '',
|
||||||
roadTypes: filterForm.value.roadType || '',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理数据为统一格式
|
// 处理数据为统一格式
|
||||||
@ -808,7 +791,6 @@ watch(
|
|||||||
district: '',
|
district: '',
|
||||||
type: '',
|
type: '',
|
||||||
roadConditionType: '',
|
roadConditionType: '',
|
||||||
roadType: '',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -103,7 +103,6 @@ const emit = defineEmits([
|
|||||||
'riskPointStatsChange',
|
'riskPointStatsChange',
|
||||||
'update:roadvalArr',
|
'update:roadvalArr',
|
||||||
'openHazardPointSituation',
|
'openHazardPointSituation',
|
||||||
'openRoadSectionSituation',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 当前选中的区县
|
// 当前选中的区县
|
||||||
@ -847,9 +846,6 @@ const addProjectMarkers = (data, iconUrl, type = 'project') => {
|
|||||||
if (type === 'riskPoint') {
|
if (type === 'riskPoint') {
|
||||||
// 风险点类型,触发父组件打开涉灾隐患点情况弹窗
|
// 风险点类型,触发父组件打开涉灾隐患点情况弹窗
|
||||||
emit('openHazardPointSituation', item);
|
emit('openHazardPointSituation', item);
|
||||||
} else if (type === 'road') {
|
|
||||||
// 路段类型,触发父组件打开路段情况弹窗
|
|
||||||
emit('openRoadSectionSituation', item);
|
|
||||||
} else {
|
} else {
|
||||||
openMapInfoDialog(type, item);
|
openMapInfoDialog(type, item);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,9 @@
|
|||||||
// 弹窗组件统一数据配置
|
// 弹窗组件统一数据配置
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue';
|
||||||
import { request } from '@/utils/request'
|
import { request } from '@/utils/request';
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
// 公路类型选项
|
|
||||||
export const roadTypeOptions = ref([
|
|
||||||
{ label: '全部', value: '' },
|
|
||||||
{ label: '国省道', value: 'G,S' },
|
|
||||||
{ label: '农村公路', value: ' X, Y, C' },
|
|
||||||
])
|
|
||||||
// 影响区域选项
|
// 影响区域选项
|
||||||
export const regionOptions = ref([])
|
export const regionOptions = ref([]);
|
||||||
|
|
||||||
// 获取影响区域选项
|
// 获取影响区域选项
|
||||||
export const fetchDistrictOptions = async () => {
|
export const fetchDistrictOptions = async () => {
|
||||||
@ -17,25 +11,25 @@ export const fetchDistrictOptions = async () => {
|
|||||||
const res = await request({
|
const res = await request({
|
||||||
url: '/snow-ops-platform/sm-event/dashboard/district-options',
|
url: '/snow-ops-platform/sm-event/dashboard/district-options',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
});
|
||||||
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
||||||
// 将接口返回的数据转换为选项格式
|
// 将接口返回的数据转换为选项格式
|
||||||
const options = res.data.map((item) => ({
|
const options = res.data.map(item => ({
|
||||||
label: item.qxmc,
|
label: item.qxmc,
|
||||||
value: item.xzdm,
|
value: item.xzdm,
|
||||||
}))
|
}));
|
||||||
// 保留"全部"选项,并添加接口返回的数据
|
// 保留"全部"选项,并添加接口返回的数据
|
||||||
regionOptions.value = [{ label: '全部', value: '' }, ...options]
|
regionOptions.value = [{ label: '全部', value: '' }, ...options];
|
||||||
return options
|
return options;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取影响区域选项失败:', error)
|
console.error('获取影响区域选项失败:', error);
|
||||||
}
|
}
|
||||||
return regionOptions.value
|
return regionOptions.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 路况类型选项(默认数据,会被API数据替换)
|
// 路况类型选项(默认数据,会被API数据替换)
|
||||||
export const typeOptions = ref([])
|
export const typeOptions = ref([]);
|
||||||
|
|
||||||
// 管控措施选项(默认数据,会被API数据替换)
|
// 管控措施选项(默认数据,会被API数据替换)
|
||||||
export const controlMeasureOptions = ref([
|
export const controlMeasureOptions = ref([
|
||||||
@ -45,7 +39,7 @@ export const controlMeasureOptions = ref([
|
|||||||
// { label: "限速限车", value: "限速限车" },
|
// { label: "限速限车", value: "限速限车" },
|
||||||
// { label: "限速", value: "限速" },
|
// { label: "限速", value: "限速" },
|
||||||
// { label: "告警阻拦", value: "告警阻拦" },
|
// { label: "告警阻拦", value: "告警阻拦" },
|
||||||
])
|
]);
|
||||||
|
|
||||||
// 获取路况类型选项
|
// 获取路况类型选项
|
||||||
export const fetchRoadConditionOptions = async () => {
|
export const fetchRoadConditionOptions = async () => {
|
||||||
@ -53,22 +47,22 @@ export const fetchRoadConditionOptions = async () => {
|
|||||||
const res = await request({
|
const res = await request({
|
||||||
url: '/snow-ops-platform/sm-event/dashboard/processing-measure-options',
|
url: '/snow-ops-platform/sm-event/dashboard/processing-measure-options',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
});
|
||||||
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
||||||
// 将接口返回的字符串数组转换为选项格式
|
// 将接口返回的字符串数组转换为选项格式
|
||||||
const options = res.data.map((item) => ({
|
const options = res.data.map(item => ({
|
||||||
label: item,
|
label: item,
|
||||||
value: item,
|
value: item,
|
||||||
}))
|
}));
|
||||||
// 保留"全部"选项,并添加接口返回的数据
|
// 保留"全部"选项,并添加接口返回的数据
|
||||||
typeOptions.value = [{ label: '全部', value: '' }, ...options]
|
typeOptions.value = [{ label: '全部', value: '' }, ...options];
|
||||||
return options
|
return options;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取路况类型选项失败:', error)
|
console.error('获取路况类型选项失败:', error);
|
||||||
}
|
}
|
||||||
return typeOptions.value
|
return typeOptions.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取管控措施选项
|
// 获取管控措施选项
|
||||||
export const fetchControlMeasureOptions = async () => {
|
export const fetchControlMeasureOptions = async () => {
|
||||||
@ -76,34 +70,34 @@ export const fetchControlMeasureOptions = async () => {
|
|||||||
const res = await request({
|
const res = await request({
|
||||||
url: '/snow-ops-platform/sm-event/dashboard/processing-measure-options',
|
url: '/snow-ops-platform/sm-event/dashboard/processing-measure-options',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
});
|
||||||
|
|
||||||
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
if (res && res.code === '00000' && Array.isArray(res.data)) {
|
||||||
const options = res.data
|
const options = res.data
|
||||||
.map((item) => {
|
.map(item => {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
return { label: item, value: item }
|
return { label: item, value: item };
|
||||||
}
|
}
|
||||||
if (item && typeof item === 'object') {
|
if (item && typeof item === 'object') {
|
||||||
const label = item.label ?? item.name ?? item.text ?? item.value ?? item.val
|
const label = item.label ?? item.name ?? item.text ?? item.value ?? item.val;
|
||||||
const value = item.value ?? item.val ?? item.code ?? label
|
const value = item.value ?? item.val ?? item.code ?? label;
|
||||||
if (label == null || value == null) return null
|
if (label == null || value == null) return null;
|
||||||
return { label: String(label), value: String(value) }
|
return { label: String(label), value: String(value) };
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean);
|
||||||
|
|
||||||
if (options.length > 0) {
|
if (options.length > 0) {
|
||||||
controlMeasureOptions.value = options
|
controlMeasureOptions.value = options;
|
||||||
return options
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取管控措施选项失败:', error)
|
console.error('获取管控措施选项失败:', error);
|
||||||
}
|
}
|
||||||
return controlMeasureOptions.value
|
return controlMeasureOptions.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 风险等级选项
|
// 风险等级选项
|
||||||
export const riskLevelOptions = [
|
export const riskLevelOptions = [
|
||||||
@ -112,7 +106,7 @@ export const riskLevelOptions = [
|
|||||||
{ label: '二级', value: '二级' },
|
{ label: '二级', value: '二级' },
|
||||||
{ label: '三级', value: '三级' },
|
{ label: '三级', value: '三级' },
|
||||||
{ label: '四级', value: '四级' },
|
{ label: '四级', value: '四级' },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 影响点类型选项
|
// 影响点类型选项
|
||||||
export const pointTypeOptions = [
|
export const pointTypeOptions = [
|
||||||
@ -121,7 +115,7 @@ export const pointTypeOptions = [
|
|||||||
{ label: '桥梁', value: 'bridge' },
|
{ label: '桥梁', value: 'bridge' },
|
||||||
{ label: '隧道', value: 'tunnel' },
|
{ label: '隧道', value: 'tunnel' },
|
||||||
{ label: '路面', value: 'road' },
|
{ label: '路面', value: 'road' },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 影响点等级选项
|
// 影响点等级选项
|
||||||
export const pointLevelOptions = [
|
export const pointLevelOptions = [
|
||||||
@ -130,14 +124,14 @@ export const pointLevelOptions = [
|
|||||||
{ label: '中风险', value: '中风险' },
|
{ label: '中风险', value: '中风险' },
|
||||||
{ label: '较高风险', value: '较高风险' },
|
{ label: '较高风险', value: '较高风险' },
|
||||||
{ label: '高风险', value: '高风险' },
|
{ label: '高风险', value: '高风险' },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 是否回应选项
|
// 是否回应选项
|
||||||
export const isRespondedOptions = [
|
export const isRespondedOptions = [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
{ label: '是', value: true },
|
{ label: '是', value: true },
|
||||||
{ label: '否', value: false },
|
{ label: '否', value: false },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 预警等级选项
|
// 预警等级选项
|
||||||
export const warningLevelOptions = [
|
export const warningLevelOptions = [
|
||||||
@ -146,277 +140,30 @@ export const warningLevelOptions = [
|
|||||||
{ label: '橙色预警', value: '橙色预警' },
|
{ label: '橙色预警', value: '橙色预警' },
|
||||||
{ label: '黄色预警', value: '黄色预警' },
|
{ label: '黄色预警', value: '黄色预警' },
|
||||||
{ label: '蓝色预警', value: '蓝色预警' },
|
{ label: '蓝色预警', value: '蓝色预警' },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 是否结束选项
|
// 是否结束选项
|
||||||
export const isEndedOptions = [
|
export const isEndedOptions = [
|
||||||
{ label: '全部', value: '' },
|
{ label: '全部', value: '' },
|
||||||
{ label: '是', value: true },
|
{ label: '是', value: true },
|
||||||
{ label: '否', value: false },
|
{ label: '否', value: false },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 影响区域选项(带全部)
|
// 影响区域选项(带全部)
|
||||||
export const regionOptionsWithAll = ref([])
|
export const regionOptionsWithAll = ref([]);
|
||||||
|
|
||||||
// 格式化日期时间为接口所需格式
|
// 格式化日期时间为接口所需格式
|
||||||
export const formatDateTime = (date) => {
|
export const formatDateTime = date => {
|
||||||
if (!date) return ''
|
if (!date) return '';
|
||||||
const d = new Date(date)
|
const d = new Date(date);
|
||||||
const year = d.getFullYear()
|
const year = d.getFullYear();
|
||||||
const month = String(d.getMonth() + 1).padStart(2, '0')
|
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||||
const day = String(d.getDate()).padStart(2, '0')
|
const day = String(d.getDate()).padStart(2, '0');
|
||||||
const hours = String(d.getHours()).padStart(2, '0')
|
const hours = String(d.getHours()).padStart(2, '0');
|
||||||
const minutes = String(d.getMinutes()).padStart(2, '0')
|
const minutes = String(d.getMinutes()).padStart(2, '0');
|
||||||
const seconds = String(d.getSeconds()).padStart(2, '0')
|
const seconds = String(d.getSeconds()).padStart(2, '0');
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 记录用户操作日志(使用 fetch keepalive 确保页面切换后请求仍能完成)
|
|
||||||
export const logUserOperation = (type, command) => {
|
|
||||||
try {
|
|
||||||
const data = { type, command }
|
|
||||||
|
|
||||||
// 使用 fetch 的 keepalive 选项确保页面卸载后请求仍能完成
|
|
||||||
fetch('/snow-ops-platform/weather-warning/users/logs', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
keepalive: true, // 关键:确保页面切换后请求仍能完成
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
console.log('日志请求完成:', response.status)
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('日志请求失败:', error)
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('日志已触发发送:', data)
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
console.error('记录操作日志失败:', error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听外部应用打开并记录日志的辅助函数
|
|
||||||
const listenForAppLaunch = (type, command) => {
|
|
||||||
let hasLogged = false
|
|
||||||
let hasLostFocus = false // 是否已经失去焦点
|
|
||||||
let focusTimer = null // 用于延迟检测的定时器
|
|
||||||
const startTime = Date.now()
|
|
||||||
console.log('开始监听外部应用打开...', { type, command, initialHidden: document.hidden, startTime })
|
|
||||||
|
|
||||||
// 确认打开外部应用
|
|
||||||
const confirmLaunch = () => {
|
|
||||||
if (hasLogged) return
|
|
||||||
hasLogged = true
|
|
||||||
console.log('确认用户点击了"打开"按钮,调用日志接口')
|
|
||||||
logUserOperation(type, command)
|
|
||||||
cleanup()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检测打开状态
|
|
||||||
const checkLaunchStatus = () => {
|
|
||||||
if (hasLogged) return
|
|
||||||
|
|
||||||
const now = Date.now()
|
|
||||||
const elapsed = now - startTime
|
|
||||||
|
|
||||||
const isHidden = document.hidden
|
|
||||||
const currentHasFocus = document.hasFocus()
|
|
||||||
|
|
||||||
console.log(`检测状态 [${elapsed}ms]:`, { isHidden, hasFocus: currentHasFocus, hasLostFocus, hasLogged })
|
|
||||||
|
|
||||||
// 情况1: 页面被隐藏 → 用户点击了"打开"
|
|
||||||
if (isHidden) {
|
|
||||||
confirmLaunch()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 情况2: 失去焦点后重新获得焦点 → 用户点击了"取消"
|
|
||||||
if (hasLostFocus && currentHasFocus) {
|
|
||||||
console.log('用户点击了"取消"按钮,不记录日志')
|
|
||||||
cleanup()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 记录当前焦点状态
|
|
||||||
if (!currentHasFocus && !hasLostFocus) {
|
|
||||||
hasLostFocus = true
|
|
||||||
console.log('页面失去焦点,开始等待用户选择...')
|
|
||||||
|
|
||||||
// 设置延迟检测:1.5秒后如果仍未获得焦点,认为用户点击了"打开"
|
|
||||||
focusTimer = setTimeout(() => {
|
|
||||||
if (!hasLogged && hasLostFocus && !document.hasFocus()) {
|
|
||||||
console.log('1.5秒未重新获得焦点,认为用户点击了"打开"')
|
|
||||||
confirmLaunch()
|
|
||||||
}
|
|
||||||
}, 1500)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方法1: 监听 visibilitychange 事件
|
|
||||||
const handleVisibilityChange = () => {
|
|
||||||
console.log('visibilitychange 触发, document.hidden:', document.hidden)
|
|
||||||
checkLaunchStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方法2: 监听 window blur 事件
|
|
||||||
const handleWindowBlur = () => {
|
|
||||||
console.log('window blur 触发')
|
|
||||||
hasLostFocus = true
|
|
||||||
// 设置延迟检测:1.5秒后如果仍未获得焦点,认为用户点击了"打开"
|
|
||||||
focusTimer = setTimeout(() => {
|
|
||||||
if (!hasLogged && hasLostFocus && !document.hasFocus()) {
|
|
||||||
console.log('1.5秒未重新获得焦点,认为用户点击了"打开"')
|
|
||||||
confirmLaunch()
|
|
||||||
}
|
|
||||||
}, 1500)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方法3: 监听 window focus 事件(判断用户是否点击取消)
|
|
||||||
const handleWindowFocus = () => {
|
|
||||||
console.log('window focus 触发')
|
|
||||||
checkLaunchStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 方法4: 定时轮询检测
|
|
||||||
let checkInterval = setInterval(() => {
|
|
||||||
checkLaunchStatus()
|
|
||||||
const elapsed = Date.now() - startTime
|
|
||||||
|
|
||||||
// 10秒后停止轮询
|
|
||||||
if (elapsed > 10000 || hasLogged) {
|
|
||||||
clearInterval(checkInterval)
|
|
||||||
}
|
|
||||||
}, 200)
|
|
||||||
|
|
||||||
// 清理函数
|
|
||||||
const cleanup = () => {
|
|
||||||
console.log('清理监听器')
|
|
||||||
clearInterval(checkInterval)
|
|
||||||
clearTimeout(focusTimer)
|
|
||||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
|
||||||
window.removeEventListener('blur', handleWindowBlur)
|
|
||||||
window.removeEventListener('focus', handleWindowFocus)
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
|
||||||
window.addEventListener('blur', handleWindowBlur)
|
|
||||||
window.addEventListener('focus', handleWindowFocus)
|
|
||||||
|
|
||||||
// 10秒后自动清理
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!hasLogged) {
|
|
||||||
console.log('10秒超时,未检测到打开操作,清理监听器')
|
|
||||||
cleanup()
|
|
||||||
}
|
|
||||||
}, 10000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开视频会议
|
|
||||||
export const openVideoConference = async (item) => {
|
|
||||||
console.log('打开视频会议:', item)
|
|
||||||
if (!item || !item.name || !item.phone) {
|
|
||||||
console.warn('缺少姓名或电话信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// 调用接口获取 user-id
|
|
||||||
const res = await request({
|
|
||||||
url: '/snow-ops-platform/weather-warning/user-id',
|
|
||||||
method: 'GET',
|
|
||||||
params: {
|
|
||||||
name: item.name,
|
|
||||||
phone: item.phone,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const userId = 1279134
|
|
||||||
if (res.code === '00000') {
|
|
||||||
// const userId = res.data
|
|
||||||
const url = `taurusykz://taurusclient/action/avmeeting/conferenceCreateByIds?title=重庆渝路畅行风险预警&isVideoConference=true&calleeStaffIds=${userId}`
|
|
||||||
window.location.href = url
|
|
||||||
// 监听用户点击"打开"按钮后记录日志
|
|
||||||
let jsobj = {
|
|
||||||
name: item.name,
|
|
||||||
phone: item.phone,
|
|
||||||
id: item.id,
|
|
||||||
userId: userId,
|
|
||||||
text: '打开视频会议',
|
|
||||||
}
|
|
||||||
logUserOperation('launch-video-conference', JSON.stringify(jsobj))
|
|
||||||
} else {
|
|
||||||
console.error('获取 user-id 失败:', res)
|
|
||||||
// 非系统用户, 操作无法执行
|
|
||||||
ElMessage.warning('非系统用户, 操作无法执行')
|
|
||||||
logUserOperation('launch-video-conference', '非系统用户, 操作无法执行')
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取 user-id 出错:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开语音通话
|
|
||||||
export const openVoiceConference = async (item) => {
|
|
||||||
console.log('打开语音通话:', item)
|
|
||||||
if (!item || !item.name || !item.phone) {
|
|
||||||
console.warn('缺少姓名或电话信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// 调用接口获取 user-id
|
|
||||||
const res = await request({
|
|
||||||
url: '/snow-ops-platform/weather-warning/user-id',
|
|
||||||
method: 'GET',
|
|
||||||
params: {
|
|
||||||
name: item.name,
|
|
||||||
phone: item.phone,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (res.code === '00000' && res.data != null) {
|
|
||||||
const userId = res.data
|
|
||||||
const url = `taurusykz://taurusclient/action/avmeeting/conferenceCreateByIds?title=重庆渝路畅行风险预警&isVideoConference=false&calleeStaffIds=${userId}`
|
|
||||||
window.location.href = url
|
|
||||||
// 监听用户点击"打开"按钮后记录日志
|
|
||||||
let jsobj = {
|
|
||||||
name: item.name,
|
|
||||||
phone: item.phone,
|
|
||||||
id: item.id,
|
|
||||||
userId: userId,
|
|
||||||
text: '打开语音通话',
|
|
||||||
}
|
|
||||||
logUserOperation('launch-audio-conference', JSON.stringify(jsobj))
|
|
||||||
} else {
|
|
||||||
console.error('获取 user-id 失败:', res)
|
|
||||||
// 非系统用户, 操作无法执行
|
|
||||||
ElMessage.warning('非系统用户, 操作无法执行')
|
|
||||||
logUserOperation('launch-audio-conference', '非系统用户, 操作无法执行')
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取 user-id 出错:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 打开拨打电话
|
|
||||||
export const opencallConference = async (item) => {
|
|
||||||
console.log('打开拨打电话:', item)
|
|
||||||
if (!item || !item.name || !item.phone) {
|
|
||||||
console.warn('缺少姓名或电话信息')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 监听用户点击"打开"按钮后记录日志
|
|
||||||
let jsobj = {
|
|
||||||
name: item.name,
|
|
||||||
phone: item.phone,
|
|
||||||
id: item.id,
|
|
||||||
userId: '',
|
|
||||||
text: '拨打电话',
|
|
||||||
}
|
|
||||||
// listenForAppLaunch('launch-audio-conference', JSON.stringify(jsobj))
|
|
||||||
logUserOperation('phone-based-confirmation', JSON.stringify(jsobj))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 默认导出所有选项
|
// 默认导出所有选项
|
||||||
export default {
|
export default {
|
||||||
@ -434,7 +181,4 @@ export default {
|
|||||||
fetchRoadConditionOptions,
|
fetchRoadConditionOptions,
|
||||||
fetchDistrictOptions,
|
fetchDistrictOptions,
|
||||||
fetchControlMeasureOptions,
|
fetchControlMeasureOptions,
|
||||||
openVideoConference,
|
};
|
||||||
openVoiceConference,
|
|
||||||
opencallConference,
|
|
||||||
}
|
|
||||||
|
|||||||
@ -4,7 +4,11 @@
|
|||||||
<img class="title_bg" src="../../assets/RiskWarning_img/一级标题栏bg@2x.png" alt="" />
|
<img class="title_bg" src="../../assets/RiskWarning_img/一级标题栏bg@2x.png" alt="" />
|
||||||
<div class="title_img_box">
|
<div class="title_img_box">
|
||||||
<img class="title_img1" src="../../assets/RiskWarning_img/位图@2x.png" alt="" />
|
<img class="title_img1" src="../../assets/RiskWarning_img/位图@2x.png" alt="" />
|
||||||
<img class="title_img2" src="../../assets/RiskWarning_img/渝路畅行-风险预警一键响应@2x.png" alt="" />
|
<img
|
||||||
|
class="title_img2"
|
||||||
|
src="../../assets/RiskWarning_img/渝路畅行-风险预警一键响应@2x.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -16,7 +20,12 @@
|
|||||||
<div class="corner corner-bottom-left"></div>
|
<div class="corner corner-bottom-left"></div>
|
||||||
<div class="corner corner-bottom-right"></div>
|
<div class="corner corner-bottom-right"></div>
|
||||||
<!-- 中心数据展示卡片 -->
|
<!-- 中心数据展示卡片 -->
|
||||||
<centerInfoCard :type="showCenterCard.type" :peopleCount="showCenterCard.value" roadCount="117" @click="handleCenterCardClick" />
|
<centerInfoCard
|
||||||
|
:type="showCenterCard.type"
|
||||||
|
:peopleCount="showCenterCard.value"
|
||||||
|
roadCount="117"
|
||||||
|
@click="handleCenterCardClick"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<left
|
<left
|
||||||
@ -31,7 +40,7 @@
|
|||||||
@openWarningSituation="openDialog('warningSituation')"
|
@openWarningSituation="openDialog('warningSituation')"
|
||||||
@openResponseStatus="openDialog('responseStatus')"
|
@openResponseStatus="openDialog('responseStatus')"
|
||||||
@openDispatchDistrict="openDialog('dispatchDistrict')"
|
@openDispatchDistrict="openDialog('dispatchDistrict')"
|
||||||
@showCenterCard="(item) => handleCenterCardClick(item)"
|
@showCenterCard="item => handleCenterCardClick(item)"
|
||||||
@openOfflineHelp="openDialog('offlineHelp')"
|
@openOfflineHelp="openDialog('offlineHelp')"
|
||||||
@openImageInspection="openDialog('imageInspection')"
|
@openImageInspection="openDialog('imageInspection')"
|
||||||
></left>
|
></left>
|
||||||
@ -61,7 +70,6 @@
|
|||||||
@riskPointStatsChange="handleRiskPointStatsChange"
|
@riskPointStatsChange="handleRiskPointStatsChange"
|
||||||
@update:roadvalArr="updateRoadvalArr"
|
@update:roadvalArr="updateRoadvalArr"
|
||||||
@openHazardPointSituation="handleOpenHazardPointSituation"
|
@openHazardPointSituation="handleOpenHazardPointSituation"
|
||||||
@openRoadSectionSituation="handleOpenRoadSectionSituation"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -119,12 +127,15 @@
|
|||||||
:message="confirmConfig.message"
|
:message="confirmConfig.message"
|
||||||
:confirm-text="confirmConfig.confirmText"
|
:confirm-text="confirmConfig.confirmText"
|
||||||
:cancel-text="confirmConfig.cancelText"
|
:cancel-text="confirmConfig.cancelText"
|
||||||
@confirm="confirmCall"
|
@confirm="closeDialog('confirm')"
|
||||||
@cancel="closeDialog('confirm')"
|
@cancel="closeDialog('confirm')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 风险点详情对话框 -->
|
<!-- 风险点详情对话框 -->
|
||||||
<riskPointDetailDialog v-model:visible="dialogVisible.riskPointDetail" @close="closeDialog('riskPointDetail')" />
|
<riskPointDetailDialog
|
||||||
|
v-model:visible="dialogVisible.riskPointDetail"
|
||||||
|
@close="closeDialog('riskPointDetail')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 影响点情况对话框 -->
|
<!-- 影响点情况对话框 -->
|
||||||
<impactPointDialog
|
<impactPointDialog
|
||||||
@ -143,10 +154,16 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 响应点详情对话框 -->
|
<!-- 响应点详情对话框 -->
|
||||||
<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
|
<responseStatusDialog
|
||||||
@ -157,7 +174,10 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- AI预警处理结果对话框 -->
|
<!-- AI预警处理结果对话框 -->
|
||||||
<aiWarningResultDialog v-model:visible="dialogVisible.aiWarningResult" @close="closeDialog('aiWarningResult')" />
|
<aiWarningResultDialog
|
||||||
|
v-model:visible="dialogVisible.aiWarningResult"
|
||||||
|
@close="closeDialog('aiWarningResult')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 潼南基本信息对话框 -->
|
<!-- 潼南基本信息对话框 -->
|
||||||
<tongnanInfoDialog
|
<tongnanInfoDialog
|
||||||
@ -193,10 +213,16 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 管控情况对话框 -->
|
<!-- 管控情况对话框 -->
|
||||||
<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
|
<dispatchDistrictDialog
|
||||||
@ -224,81 +250,89 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 隧道信息对话框 -->
|
<!-- 隧道信息对话框 -->
|
||||||
<tunnelInfoDialog v-model:visible="dialogVisible.tunnelInfo" @close="closeDialog('tunnelInfo')" />
|
<tunnelInfoDialog
|
||||||
|
v-model:visible="dialogVisible.tunnelInfo"
|
||||||
|
@close="closeDialog('tunnelInfo')"
|
||||||
|
/>
|
||||||
|
|
||||||
<hazardPointSituationDialog
|
<hazardPointSituationDialog
|
||||||
v-model:visible="dialogVisible.hazardPointSituation"
|
v-model:visible="dialogVisible.hazardPointSituation"
|
||||||
:data="hazardPointData"
|
:data="hazardPointData"
|
||||||
:title="hazardPointDialogTitle"
|
|
||||||
@close="closeDialog('hazardPointSituation')"
|
@close="closeDialog('hazardPointSituation')"
|
||||||
@voice="openVoiceConference"
|
|
||||||
@video="openVideoConference"
|
|
||||||
@call="handleCallClick"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<offlineHelpDialog v-model:visible="dialogVisible.offlineHelp" @close="closeDialog('offlineHelp')" />
|
<offlineHelpDialog
|
||||||
|
v-model:visible="dialogVisible.offlineHelp"
|
||||||
|
@close="closeDialog('offlineHelp')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 抽查人次对话框 -->
|
<!-- 抽查人次对话框 -->
|
||||||
<imageInspectionDialog v-model:visible="dialogVisible.imageInspection" @close="closeDialog('imageInspection')" />
|
<imageInspectionDialog
|
||||||
|
v-model:visible="dialogVisible.imageInspection"
|
||||||
|
@close="closeDialog('imageInspection')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 巡查里程对话框 -->
|
<!-- 巡查里程对话框 -->
|
||||||
<patrolMileageDialog v-model:visible="dialogVisible.patrolMileage" @close="closeDialog('patrolMileage')" />
|
<patrolMileageDialog
|
||||||
|
v-model:visible="dialogVisible.patrolMileage"
|
||||||
|
@close="closeDialog('patrolMileage')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 巡查情况对话框 -->
|
<!-- 巡查情况对话框 -->
|
||||||
<patrolSituationDialog v-model:visible="dialogVisible.patrolSituation" @close="closeDialog('patrolSituation')" />
|
<patrolSituationDialog
|
||||||
|
v-model:visible="dialogVisible.patrolSituation"
|
||||||
|
@close="closeDialog('patrolSituation')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, provide } from 'vue'
|
import { ref, onMounted, provide } from 'vue';
|
||||||
import useMapStore from '@/map/stores/mapStore'
|
import useMapStore from '@/map/stores/mapStore';
|
||||||
import { useMapBase } from '../cockpit/composables/useMapBase'
|
import { useMapBase } from '../cockpit/composables/useMapBase';
|
||||||
import left from './left.vue'
|
import left from './left.vue';
|
||||||
import right from './right.vue'
|
import right from './right.vue';
|
||||||
import bottom from './bottom.vue'
|
import bottom from './bottom.vue';
|
||||||
import top from './top.vue'
|
import top from './top.vue';
|
||||||
import ChongqingMap from './component/ChongqingMap.vue'
|
import ChongqingMap from './component/ChongqingMap.vue';
|
||||||
import {
|
import {
|
||||||
fetchRoadConditionOptions,
|
fetchRoadConditionOptions,
|
||||||
fetchDistrictOptions,
|
fetchDistrictOptions,
|
||||||
fetchControlMeasureOptions,
|
fetchControlMeasureOptions,
|
||||||
openVideoConference,
|
} from './component/index.js';
|
||||||
openVoiceConference,
|
|
||||||
opencallConference,
|
|
||||||
} from './component/index.js'
|
|
||||||
|
|
||||||
// 引入所有弹窗组件
|
// 引入所有弹窗组件
|
||||||
import responseSituationDiaLog from './Dialog/responseSituationDiaLog.vue'
|
import responseSituationDiaLog from './Dialog/responseSituationDiaLog.vue';
|
||||||
import warningInfoDialog from './Dialog/warningInfoDialog.vue'
|
import warningInfoDialog from './Dialog/warningInfoDialog.vue';
|
||||||
import eventDetailDialog from './Dialog/eventDetailDialog.vue'
|
import eventDetailDialog from './Dialog/eventDetailDialog.vue';
|
||||||
import confirmDialog from './Dialog/confirmDialog.vue'
|
import confirmDialog from './Dialog/confirmDialog.vue';
|
||||||
import riskPointDetailDialog from './Dialog/riskPointDetailDialog.vue'
|
import riskPointDetailDialog from './Dialog/riskPointDetailDialog.vue';
|
||||||
import impactPointDialog from './Dialog/impactPointDialog.vue'
|
import impactPointDialog from './Dialog/impactPointDialog.vue';
|
||||||
import impactPointDetailDialog from './Dialog/impactPointDetailDialog.vue'
|
import impactPointDetailDialog from './Dialog/impactPointDetailDialog.vue';
|
||||||
import responsePointDetailDialog from './Dialog/responsePointDetailDialog.vue'
|
import responsePointDetailDialog from './Dialog/responsePointDetailDialog.vue';
|
||||||
import responsePointInfoDialog from './Dialog/responsePointInfoDialog.vue'
|
import responsePointInfoDialog from './Dialog/responsePointInfoDialog.vue';
|
||||||
import responseStatusDialog from './Dialog/responseStatusDialog.vue'
|
import responseStatusDialog from './Dialog/responseStatusDialog.vue';
|
||||||
import aiWarningResultDialog from './Dialog/aiWarningResultDialog.vue'
|
import aiWarningResultDialog from './Dialog/aiWarningResultDialog.vue';
|
||||||
import tongnanInfoDialog from './Dialog/tongnanInfoDialog.vue'
|
import tongnanInfoDialog from './Dialog/tongnanInfoDialog.vue';
|
||||||
import tongnanResponsibleDialog from './Dialog/tongnanResponsibleDialog.vue'
|
import tongnanResponsibleDialog from './Dialog/tongnanResponsibleDialog.vue';
|
||||||
import clearanceSituationDialog from './Dialog/clearanceSituationDialog.vue'
|
import clearanceSituationDialog from './Dialog/clearanceSituationDialog.vue';
|
||||||
import controlSituationDialog from './Dialog/controlSituationDialog.vue'
|
import controlSituationDialog from './Dialog/controlSituationDialog.vue';
|
||||||
import dispatchDetailDialog from './Dialog/dispatchDetailDialog.vue'
|
import dispatchDetailDialog from './Dialog/dispatchDetailDialog.vue';
|
||||||
import dispatchDistrictDialog from './Dialog/dispatchDistrictDialog.vue'
|
import dispatchDistrictDialog from './Dialog/dispatchDistrictDialog.vue';
|
||||||
import tongnanTeamDialog from './Dialog/tongnanTeamDialog.vue'
|
import tongnanTeamDialog from './Dialog/tongnanTeamDialog.vue';
|
||||||
import warningSituationDialog from './Dialog/warningSituationDialog.vue'
|
import warningSituationDialog from './Dialog/warningSituationDialog.vue';
|
||||||
import tunnelInfoDialog from './Dialog/tunnelInfoDialog.vue'
|
import tunnelInfoDialog from './Dialog/tunnelInfoDialog.vue';
|
||||||
import centerInfoCard from './Dialog/centerInfoCard.vue'
|
import centerInfoCard from './Dialog/centerInfoCard.vue';
|
||||||
import tongnanProjectPersonDialog from './Dialog/tongnanProjectPersonDialog.vue'
|
import tongnanProjectPersonDialog from './Dialog/tongnanProjectPersonDialog.vue';
|
||||||
import hazardPointSituationDialog from './Dialog/hazardPointSituationDialog.vue'
|
import hazardPointSituationDialog from './Dialog/hazardPointSituationDialog.vue';
|
||||||
import offlineHelpDialog from './Dialog/offlineHelpDialog.vue'
|
import offlineHelpDialog from './Dialog/offlineHelpDialog.vue';
|
||||||
import imageInspectionDialog from './Dialog/imageInspectionDialog.vue'
|
import imageInspectionDialog from './Dialog/imageInspectionDialog.vue';
|
||||||
import patrolMileageDialog from './Dialog/patrolMileageDialog.vue'
|
import patrolMileageDialog from './Dialog/patrolMileageDialog.vue';
|
||||||
import patrolSituationDialog from './Dialog/patrolSituationDialog.vue'
|
import patrolSituationDialog from './Dialog/patrolSituationDialog.vue';
|
||||||
|
|
||||||
import './component/el-select.scss'
|
import './component/el-select.scss';
|
||||||
import './component/date-picker-theme.scss'
|
import './component/date-picker-theme.scss';
|
||||||
|
|
||||||
// 弹窗显示状态
|
// 弹窗显示状态
|
||||||
const dialogVisible = ref({
|
const dialogVisible = ref({
|
||||||
@ -328,8 +362,8 @@ const dialogVisible = ref({
|
|||||||
imageInspection: false,
|
imageInspection: false,
|
||||||
patrolMileage: false,
|
patrolMileage: false,
|
||||||
patrolSituation: false,
|
patrolSituation: false,
|
||||||
})
|
});
|
||||||
const activeitem = ref({})
|
const activeitem = ref({});
|
||||||
|
|
||||||
// 风险点统计数据
|
// 风险点统计数据
|
||||||
const riskPointStats = ref({
|
const riskPointStats = ref({
|
||||||
@ -340,186 +374,169 @@ const riskPointStats = ref({
|
|||||||
一般路内隐患点: 0,
|
一般路内隐患点: 0,
|
||||||
一般路外隐患点: 0,
|
一般路外隐患点: 0,
|
||||||
风险点总数: 0,
|
风险点总数: 0,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 涉灾隐患点数据
|
// 涉灾隐患点数据
|
||||||
const hazardPointData = ref({})
|
const hazardPointData = ref({});
|
||||||
|
|
||||||
// 弹窗标题
|
|
||||||
const hazardPointDialogTitle = ref('涉灾隐患点情况')
|
|
||||||
|
|
||||||
// 日期范围
|
// 日期范围
|
||||||
const getdateRange = ref([])
|
const getdateRange = ref([]);
|
||||||
|
|
||||||
// 处理日期范围变化
|
// 处理日期范围变化
|
||||||
const handleDateRangeChange = (val) => {
|
const handleDateRangeChange = val => {
|
||||||
console.log('日期范围变化:', val)
|
console.log('日期范围变化:', val);
|
||||||
getdateRange.value = val
|
getdateRange.value = val;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 地图组件引用
|
// 地图组件引用
|
||||||
const chongqingMapRef = ref(null)
|
const chongqingMapRef = ref(null);
|
||||||
|
|
||||||
// 切换导航项时触发
|
// 切换导航项时触发
|
||||||
const changeActiveIndex = (index) => {
|
const changeActiveIndex = index => {
|
||||||
activeitem.value = index
|
activeitem.value = index;
|
||||||
}
|
};
|
||||||
const roadItem = ref({})
|
const roadItem = ref({});
|
||||||
const showRoadStats = ref(false)
|
const showRoadStats = ref(false);
|
||||||
const roadItemClick = (item) => {
|
const roadItemClick = item => {
|
||||||
console.log('点击路段:', item)
|
console.log('点击路段:', item);
|
||||||
roadItem.value = item
|
roadItem.value = item;
|
||||||
showRoadStats.value = true
|
showRoadStats.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理隐藏路段统计
|
// 处理隐藏路段统计
|
||||||
const handleHideRoadStats = () => {
|
const handleHideRoadStats = () => {
|
||||||
console.log('隐藏路段统计')
|
console.log('隐藏路段统计');
|
||||||
showRoadStats.value = false
|
showRoadStats.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理隐患点点击
|
// 处理隐患点点击
|
||||||
const handleHazardItemClick = (item) => {
|
const handleHazardItemClick = item => {
|
||||||
console.log('点击隐患点:', item)
|
console.log('点击隐患点:', item);
|
||||||
// 调用地图组件的方法获取风险点数据
|
// 调用地图组件的方法获取风险点数据
|
||||||
if (chongqingMapRef.value) {
|
if (chongqingMapRef.value) {
|
||||||
chongqingMapRef.value.handleHazardItemClick(item)
|
chongqingMapRef.value.handleHazardItemClick(item);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const showHazardPopup = ref(false)
|
const showHazardPopup = ref(false);
|
||||||
const showHazardPopupfn = (val) => {
|
const showHazardPopupfn = val => {
|
||||||
showHazardPopup.value = val
|
showHazardPopup.value = val;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理风险点统计数据变化
|
// 处理风险点统计数据变化
|
||||||
const handleRiskPointStatsChange = (stats) => {
|
const handleRiskPointStatsChange = stats => {
|
||||||
console.log('风险点统计数据变化:', stats)
|
console.log('风险点统计数据变化:', stats);
|
||||||
riskPointStats.value = stats
|
riskPointStats.value = stats;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 路段统计数据
|
// 路段统计数据
|
||||||
const roadvalArrtrue = ref([])
|
const roadvalArrtrue = ref([]);
|
||||||
const updateRoadvalArr = (roadvalArr) => {
|
const updateRoadvalArr = roadvalArr => {
|
||||||
roadvalArrtrue.value = roadvalArr
|
roadvalArrtrue.value = roadvalArr;
|
||||||
// let num = 0;
|
// let num = 0;
|
||||||
// roadvalArrtrue.value.forEach(item => {
|
// roadvalArrtrue.value.forEach(item => {
|
||||||
// num += item.value;
|
// num += item.value;
|
||||||
// });
|
// });
|
||||||
// roadvalArrtrue.value.push({ label: '风险点总数', value: num });
|
// roadvalArrtrue.value.push({ label: '风险点总数', value: num });
|
||||||
console.log('更新路段统计数据:', roadvalArr)
|
console.log('更新路段统计数据:', roadvalArr);
|
||||||
console.log('更新路段统计数据:', roadvalArrtrue)
|
console.log('更新路段统计数据:', roadvalArrtrue);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开资源详情(队伍、人员、装备、物资)
|
// 打开资源详情(队伍、人员、装备、物资)
|
||||||
const openResourceDetail = (item) => {
|
const openResourceDetail = item => {
|
||||||
console.log('打开资源详情:', item)
|
console.log('打开资源详情:', item);
|
||||||
// 判断是否为队伍或人员
|
// 判断是否为队伍或人员
|
||||||
if (item.label === '全市普通公路抢险队伍' || item.label === '人员') {
|
if (item.label === '全市普通公路抢险队伍' || item.label === '人员') {
|
||||||
// 调用地图组件的获取应急力量方法
|
// 调用地图组件的获取应急力量方法
|
||||||
if (chongqingMapRef.value) {
|
if (chongqingMapRef.value) {
|
||||||
chongqingMapRef.value.getEmergencyForceData()
|
chongqingMapRef.value.getEmergencyForceData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 打开对应的弹窗
|
// 打开对应的弹窗
|
||||||
const key = item.label.toLowerCase().replace(/[^a-z]/g, '')
|
const key = item.label.toLowerCase().replace(/[^a-z]/g, '');
|
||||||
if (dialogVisible.value[key] !== undefined) {
|
if (dialogVisible.value[key] !== undefined) {
|
||||||
dialogVisible.value[key] = true
|
dialogVisible.value[key] = true;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 清除地图标记
|
// 清除地图标记
|
||||||
const clearMapMarkers = () => {
|
const clearMapMarkers = () => {
|
||||||
console.log('清除地图标记')
|
console.log('清除地图标记');
|
||||||
if (chongqingMapRef.value) {
|
if (chongqingMapRef.value) {
|
||||||
chongqingMapRef.value.clearProjectMarkers()
|
chongqingMapRef.value.clearProjectMarkers();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理清除筛选事件
|
// 处理清除筛选事件
|
||||||
const handleClearFilters = () => {
|
const handleClearFilters = () => {
|
||||||
console.log('index.vue 处理清除筛选事件')
|
console.log('index.vue 处理清除筛选事件');
|
||||||
// 清除地图标记
|
// 清除地图标记
|
||||||
clearMapMarkers()
|
clearMapMarkers();
|
||||||
// 重置相关状态
|
// 重置相关状态
|
||||||
activeitem.value = {}
|
activeitem.value = {};
|
||||||
roadItem.value = {}
|
roadItem.value = {};
|
||||||
showHazardPopup.value = false
|
showHazardPopup.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 打开弹窗
|
// 打开弹窗
|
||||||
const openDialog = (dialogName) => {
|
const openDialog = dialogName => {
|
||||||
dialogVisible.value[dialogName] = true
|
dialogVisible.value[dialogName] = true;
|
||||||
}
|
};
|
||||||
const impactPointDetailItem = ref({})
|
const impactPointDetailItem = ref({});
|
||||||
// 处理影响点点击
|
// 处理影响点点击
|
||||||
const handleImpactPointClick = (item) => {
|
const handleImpactPointClick = item => {
|
||||||
console.log('影响点点击:', item)
|
console.log('影响点点击:', item);
|
||||||
impactPointDetailItem.value = item
|
impactPointDetailItem.value = item;
|
||||||
}
|
};
|
||||||
const handleImpactItem = ref({})
|
const handleImpactItem = ref({});
|
||||||
const handleImpactClickItem = (item) => {
|
const handleImpactClickItem = item => {
|
||||||
console.log('影响点点击详情:', item)
|
console.log('影响点点击详情:', item);
|
||||||
handleImpactItem.value = item
|
handleImpactItem.value = item;
|
||||||
}
|
};
|
||||||
const tongnanInfoItemData = ref({})
|
const tongnanInfoItemData = ref({});
|
||||||
const tongnanInfoItemDatafn = (item) => {
|
const tongnanInfoItemDatafn = item => {
|
||||||
console.log('点击详情:', item)
|
console.log('点击详情:', item);
|
||||||
tongnanInfoItemData.value = item
|
tongnanInfoItemData.value = item;
|
||||||
}
|
};
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
const closeDialog = (dialogName) => {
|
const closeDialog = dialogName => {
|
||||||
// 关闭弹窗时,重置弹窗数据
|
// 关闭弹窗时,重置弹窗数据
|
||||||
console.log('关闭弹窗', dialogName)
|
console.log('关闭弹窗', dialogName);
|
||||||
dialogVisible.value[dialogName] = false
|
dialogVisible.value[dialogName] = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理打开涉灾隐患点情况弹窗
|
// 处理打开涉灾隐患点情况弹窗
|
||||||
const handleOpenHazardPointSituation = (item) => {
|
const handleOpenHazardPointSituation = item => {
|
||||||
console.log('打开涉灾隐患点情况弹窗:', item)
|
console.log('打开涉灾隐患点情况弹窗:', item);
|
||||||
hazardPointDialogTitle.value = '涉灾隐患点情况'
|
hazardPointData.value = item;
|
||||||
hazardPointData.value = item
|
dialogVisible.value.hazardPointSituation = true;
|
||||||
dialogVisible.value.hazardPointSituation = true
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// 处理打开路段情况弹窗
|
|
||||||
const handleOpenRoadSectionSituation = (item) => {
|
|
||||||
console.log('打开路段情况弹窗:', item)
|
|
||||||
hazardPointDialogTitle.value = '路段情况'
|
|
||||||
// 添加数据类型标识
|
|
||||||
hazardPointData.value = {
|
|
||||||
...item,
|
|
||||||
dataType: 'road',
|
|
||||||
}
|
|
||||||
dialogVisible.value.hazardPointSituation = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理气象预警点击
|
// 处理气象预警点击
|
||||||
const warningitem = ref({})
|
const warningitem = ref({});
|
||||||
const handleWarningClick = (item) => {
|
const handleWarningClick = item => {
|
||||||
console.log('气象预警点击:', item)
|
console.log('气象预警点击:', item);
|
||||||
warningitem.value = item
|
warningitem.value = item;
|
||||||
}
|
};
|
||||||
|
|
||||||
const clearanceSituationDialogItemData = ref({})
|
const clearanceSituationDialogItemData = ref({});
|
||||||
const handleItemData = (item) => {
|
const handleItemData = item => {
|
||||||
console.log('点击详情:', item)
|
console.log('点击详情:', item);
|
||||||
clearanceSituationDialogItemData.value = item
|
clearanceSituationDialogItemData.value = item;
|
||||||
}
|
};
|
||||||
|
|
||||||
const dispatchDateRange = ref([])
|
const dispatchDateRange = ref([]);
|
||||||
const handleDispatchDateRange = (range) => {
|
const handleDispatchDateRange = range => {
|
||||||
dispatchDateRange.value = range
|
dispatchDateRange.value = range;
|
||||||
}
|
};
|
||||||
const rightDateRange = ref([])
|
const rightDateRange = ref([]);
|
||||||
const updateDateRange = (range) => {
|
const updateDateRange = range => {
|
||||||
console.log('更新日期范围:', range)
|
console.log('更新日期范围:', range);
|
||||||
rightDateRange.value = range
|
rightDateRange.value = range;
|
||||||
}
|
};
|
||||||
const filterForm = ref({})
|
const filterForm = ref({});
|
||||||
const updateFilterForm = (item) => {
|
const updateFilterForm = item => {
|
||||||
console.log('更新筛选表单:', item)
|
console.log('更新筛选表单:', item);
|
||||||
filterForm.value = item
|
filterForm.value = item;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 确认对话框配置
|
// 确认对话框配置
|
||||||
const confirmConfig = ref({
|
const confirmConfig = ref({
|
||||||
@ -527,82 +544,63 @@ const confirmConfig = ref({
|
|||||||
message: '是否拨打电话?',
|
message: '是否拨打电话?',
|
||||||
confirmText: '确定',
|
confirmText: '确定',
|
||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
})
|
});
|
||||||
// 当前要拨打的电话信息
|
|
||||||
const currentCallItem = ref(null)
|
|
||||||
// 处理电话按钮点击
|
|
||||||
const handleCallClick = (item) => {
|
|
||||||
console.log('准备拨打电话:', item)
|
|
||||||
currentCallItem.value = item
|
|
||||||
openConfirm({
|
|
||||||
title: '拨打电话',
|
|
||||||
message: `是否拨打电话: ${item.phone || item.name || ''}?`,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 打开确认对话框
|
|
||||||
const openConfirm = (config) => {
|
|
||||||
confirmConfig.value = { ...confirmConfig.value, ...config }
|
|
||||||
dialogVisible.value.confirm = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认拨打电话
|
// 打开确认对话框
|
||||||
const confirmCall = () => {
|
const openConfirm = config => {
|
||||||
if (currentCallItem.value) {
|
confirmConfig.value = { ...confirmConfig.value, ...config };
|
||||||
opencallConference(currentCallItem.value)
|
dialogVisible.value.confirm = true;
|
||||||
currentCallItem.value = null
|
};
|
||||||
}
|
|
||||||
closeDialog('confirm')
|
|
||||||
}
|
|
||||||
// 中心信息卡片显示状态
|
// 中心信息卡片显示状态
|
||||||
const showCenterCard = ref(false)
|
const showCenterCard = ref(false);
|
||||||
const allCountyData = ref({})
|
const allCountyData = ref({});
|
||||||
// 处理区县点击
|
// 处理区县点击
|
||||||
const handleDistrictClick = (item) => {
|
const handleDistrictClick = item => {
|
||||||
console.log('区县点击:', item)
|
console.log('区县点击:', item);
|
||||||
allCountyData.value = item
|
allCountyData.value = item;
|
||||||
if (item.data.roadType == 'national') {
|
if (item.data.roadType == 'national') {
|
||||||
// 国省道
|
// 国省道
|
||||||
openDialog('tongnanTeam')
|
openDialog('tongnanTeam');
|
||||||
} else if (item.data.roadType == 'rural') {
|
} else if (item.data.roadType == 'rural') {
|
||||||
openDialog('responseSituation')
|
openDialog('responseSituation');
|
||||||
} else if (item.data.type == 'project' && item.data.roadType == '-') {
|
} else if (item.data.type == 'project' && item.data.roadType == '-') {
|
||||||
// 项目
|
// 项目
|
||||||
openDialog('tongnanResponsible')
|
openDialog('tongnanResponsible');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理中心卡片点击
|
// 处理中心卡片点击
|
||||||
const handleCenterCardClick = (item) => {
|
const handleCenterCardClick = item => {
|
||||||
console.log('中心卡片点击:', item)
|
console.log('中心卡片点击:', item);
|
||||||
|
|
||||||
// 调用地图组件的方法打开中心信息卡片弹窗
|
// 调用地图组件的方法打开中心信息卡片弹窗
|
||||||
if (chongqingMapRef.value && item.data) {
|
if (chongqingMapRef.value && item.data) {
|
||||||
const cardData = {
|
const cardData = {
|
||||||
title: getCardTitleByType(item.type),
|
title: getCardTitleByType(item.type),
|
||||||
dataList: item.data,
|
dataList: item.data,
|
||||||
}
|
};
|
||||||
chongqingMapRef.value.openCenterCard(cardData)
|
chongqingMapRef.value.openCenterCard(cardData);
|
||||||
|
|
||||||
// 如果数据中包含区县信息,定位到第一个区县
|
// 如果数据中包含区县信息,定位到第一个区县
|
||||||
if (item.data.length > 0 && (item.data[0].countyName || item.data[0].name)) {
|
if (item.data.length > 0 && (item.data[0].countyName || item.data[0].name)) {
|
||||||
const firstCounty = item.data[0].countyName || item.data[0].name
|
const firstCounty = item.data[0].countyName || item.data[0].name;
|
||||||
chongqingMapRef.value.locateToDistrict(firstCounty)
|
chongqingMapRef.value.locateToDistrict(firstCounty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 根据类型获取卡片标题
|
// 根据类型获取卡片标题
|
||||||
const getCardTitleByType = (type) => {
|
const getCardTitleByType = type => {
|
||||||
const titleMap = {
|
const titleMap = {
|
||||||
first: '国省道调度',
|
first: '国省道调度',
|
||||||
second: '农村公路调度',
|
second: '农村公路调度',
|
||||||
third: '建设工程调度',
|
third: '建设工程调度',
|
||||||
}
|
};
|
||||||
return titleMap[type] || '调度统计'
|
return titleMap[type] || '调度统计';
|
||||||
}
|
};
|
||||||
const handleCenterCardClickType = (item) => {
|
const handleCenterCardClickType = item => {
|
||||||
console.log(item.data)
|
console.log(item.data);
|
||||||
showCenterCard.value = true
|
showCenterCard.value = true;
|
||||||
// if (item.type === "second") {
|
// if (item.type === "second") {
|
||||||
// openDialog("tongnanTeam");
|
// openDialog("tongnanTeam");
|
||||||
// } else if (item.type === "third") {
|
// } else if (item.type === "third") {
|
||||||
@ -610,47 +608,47 @@ const handleCenterCardClickType = (item) => {
|
|||||||
// } else if (item.type === "first") {
|
// } else if (item.type === "first") {
|
||||||
// openDialog("warningSituation");
|
// openDialog("warningSituation");
|
||||||
// }
|
// }
|
||||||
}
|
};
|
||||||
|
|
||||||
// 兄弟组件通信机制
|
// 兄弟组件通信机制
|
||||||
const refreshLeftData = ref(null)
|
const refreshLeftData = ref(null);
|
||||||
const refreshRightData = ref(null)
|
const refreshRightData = ref(null);
|
||||||
|
|
||||||
// 提供刷新函数给子组件
|
// 提供刷新函数给子组件
|
||||||
const setRefreshLeftData = (callback) => {
|
const setRefreshLeftData = callback => {
|
||||||
refreshLeftData.value = callback
|
refreshLeftData.value = callback;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提供刷新函数给 right.vue
|
// 提供刷新函数给 right.vue
|
||||||
const setRefreshRightData = (callback) => {
|
const setRefreshRightData = callback => {
|
||||||
refreshRightData.value = callback
|
refreshRightData.value = callback;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 触发刷新函数
|
// 触发刷新函数
|
||||||
const triggerRefreshLeftData = () => {
|
const triggerRefreshLeftData = () => {
|
||||||
if (refreshLeftData.value) {
|
if (refreshLeftData.value) {
|
||||||
refreshLeftData.value()
|
refreshLeftData.value();
|
||||||
}
|
}
|
||||||
// 同时触发 right.vue 刷新
|
// 同时触发 right.vue 刷新
|
||||||
if (refreshRightData.value) {
|
if (refreshRightData.value) {
|
||||||
refreshRightData.value()
|
refreshRightData.value();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 提供通信机制给子组件
|
// 提供通信机制给子组件
|
||||||
provide('setRefreshLeftData', setRefreshLeftData)
|
provide('setRefreshLeftData', setRefreshLeftData);
|
||||||
provide('triggerRefreshLeftData', triggerRefreshLeftData)
|
provide('triggerRefreshLeftData', triggerRefreshLeftData);
|
||||||
provide('setRefreshRightData', setRefreshRightData)
|
provide('setRefreshRightData', setRefreshRightData);
|
||||||
provide('getdateRange', getdateRange)
|
provide('getdateRange', getdateRange);
|
||||||
|
|
||||||
// ==================== 地图状态管理 ====================
|
// ==================== 地图状态管理 ====================
|
||||||
|
|
||||||
const mapStore = useMapStore()
|
const mapStore = useMapStore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载地图的业务底图与聚焦中心点
|
* 加载地图的业务底图与聚焦中心点
|
||||||
*/
|
*/
|
||||||
const mapBase = useMapBase(mapStore)
|
const mapBase = useMapBase(mapStore);
|
||||||
|
|
||||||
// ==================== 生命周期 ====================
|
// ==================== 生命周期 ====================
|
||||||
|
|
||||||
@ -659,11 +657,11 @@ const mapBase = useMapBase(mapStore)
|
|||||||
*/
|
*/
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 加载地图业务底图 并 聚焦中心点
|
// 加载地图业务底图 并 聚焦中心点
|
||||||
mapBase.loadBaseData()
|
mapBase.loadBaseData();
|
||||||
fetchRoadConditionOptions() // 获取路况类型选项
|
fetchRoadConditionOptions(); // 获取路况类型选项
|
||||||
fetchDistrictOptions() // 获取区县选项
|
fetchDistrictOptions(); // 获取区县选项
|
||||||
fetchControlMeasureOptions() // 获取管控措施选项
|
fetchControlMeasureOptions(); // 获取管控措施选项
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="filter-header">
|
<div class="filter-header">
|
||||||
<div class="filter-container">
|
<div class="filter-container">
|
||||||
<!-- <span class="filter-item active" @click="handleDateRangeClick()">本轮</span> -->
|
<span class="filter-item active" @click="handleDateRangeClick()">本轮</span>
|
||||||
<span class="filter-item active" @click="handleDateRangeClick('total')">累计</span>
|
|
||||||
<span class="filter-item active" @click="handleDateRangeClick('today')">今日</span>
|
|
||||||
<div class="date-range-wrapper">
|
<div class="date-range-wrapper">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="dateRange"
|
v-model="dateRange"
|
||||||
@ -19,7 +17,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="hazard-stats" v-if="showHazardPopup">
|
<div class="hazard-stats" v-if="showHazardPopup">
|
||||||
<div v-for="(item, index) in hazardStatsShowArr" :key="index" class="stat-item" :class="item.class">
|
<div
|
||||||
|
v-for="(item, index) in hazardStatsShowArr"
|
||||||
|
:key="index"
|
||||||
|
class="stat-item"
|
||||||
|
:class="item.class"
|
||||||
|
>
|
||||||
<span class="stat-label">{{ item.label }}</span>
|
<span class="stat-label">{{ item.label }}</span>
|
||||||
<span class="stat-value-container display ai_center">
|
<span class="stat-value-container display ai_center">
|
||||||
<span class="stat-value">{{ item.value }}</span>
|
<span class="stat-value">{{ item.value }}</span>
|
||||||
@ -40,9 +43,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, inject, defineProps, nextTick, provide, onMounted } from 'vue'
|
import { ref, watch, inject, defineProps, nextTick, provide, onMounted } from 'vue';
|
||||||
import { Calendar } from '@element-plus/icons-vue'
|
import { Calendar } from '@element-plus/icons-vue';
|
||||||
import { request } from '@/utils/request'
|
import { request } from '@/utils/request';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
riskPointStats: {
|
riskPointStats: {
|
||||||
@ -65,26 +68,26 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
watch(
|
watch(
|
||||||
() => props.showHazardPopup,
|
() => props.showHazardPopup,
|
||||||
(newShow) => {
|
newShow => {
|
||||||
hazardStatsShowArr.value = JSON.parse(JSON.stringify([]))
|
hazardStatsShowArr.value = JSON.parse(JSON.stringify([]));
|
||||||
hazardStats.value.forEach((item) => {
|
hazardStats.value.forEach(item => {
|
||||||
item.value = 0
|
item.value = 0;
|
||||||
item.show = false
|
item.show = false;
|
||||||
})
|
});
|
||||||
},
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
const emit = defineEmits(['openAIResult', 'dateRangeChange'])
|
const emit = defineEmits(['openAIResult', 'dateRangeChange']);
|
||||||
|
|
||||||
// 注入兄弟组件通信机制
|
// 注入兄弟组件通信机制
|
||||||
const triggerRefreshLeftData = inject('triggerRefreshLeftData')
|
const triggerRefreshLeftData = inject('triggerRefreshLeftData');
|
||||||
const dateRange = ref([])
|
const dateRange = ref([]);
|
||||||
|
|
||||||
// 隐患点统计数据
|
// 隐患点统计数据
|
||||||
const hazardStatsShowArr = ref([])
|
const hazardStatsShowArr = ref([]);
|
||||||
const hazardStats = ref([
|
const hazardStats = ref([
|
||||||
{ label: '重大路内隐患点', value: 0, show: false, type: '重大路内隐患点', isWithinRedLine: '是' },
|
{ label: '重大路内隐患点', value: 0, show: false, type: '重大路内隐患点', isWithinRedLine: '是' },
|
||||||
{ label: '重大路外隐患点', value: 0, show: false, type: '重大路外隐患点', isWithinRedLine: '否' },
|
{ label: '重大路外隐患点', value: 0, show: false, type: '重大路外隐患点', isWithinRedLine: '否' },
|
||||||
@ -93,7 +96,7 @@ const hazardStats = ref([
|
|||||||
{ label: '一般路内隐患点', value: 0, show: false, type: '一般路内隐患点', isWithinRedLine: '是' },
|
{ label: '一般路内隐患点', value: 0, show: false, type: '一般路内隐患点', isWithinRedLine: '是' },
|
||||||
{ label: '一般路外隐患点', value: 0, show: false, type: '一般路外隐患点', isWithinRedLine: '否' },
|
{ label: '一般路外隐患点', value: 0, show: false, type: '一般路外隐患点', isWithinRedLine: '否' },
|
||||||
{ label: '风险点总数', value: 0, show: false, type: '风险点总数', isWithinRedLine: '' },
|
{ label: '风险点总数', value: 0, show: false, type: '风险点总数', isWithinRedLine: '' },
|
||||||
])
|
]);
|
||||||
|
|
||||||
// 路段统计数据
|
// 路段统计数据
|
||||||
const roadStats = ref([
|
const roadStats = ref([
|
||||||
@ -102,24 +105,28 @@ const roadStats = ref([
|
|||||||
{ label: '中风险路段', value: 0, type: '中风险路段' },
|
{ label: '中风险路段', value: 0, type: '中风险路段' },
|
||||||
{ label: '低风险路段', value: 0, type: '低风险路段' },
|
{ label: '低风险路段', value: 0, type: '低风险路段' },
|
||||||
{ label: '风险点总数', value: 0, type: '风险点总数' },
|
{ label: '风险点总数', value: 0, type: '风险点总数' },
|
||||||
])
|
]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.riskPointStats,
|
() => props.riskPointStats,
|
||||||
(newStats) => {
|
newStats => {
|
||||||
console.log('top.vue 收到风险点统计数据:', newStats)
|
console.log('top.vue 收到风险点统计数据:', newStats);
|
||||||
if (newStats) {
|
if (newStats) {
|
||||||
hazardStatsShowArr.value = []
|
hazardStatsShowArr.value = [];
|
||||||
hazardStats.value.forEach((item) => {
|
hazardStats.value.forEach(item => {
|
||||||
if (item.label.includes(newStats.riskLevel) && newStats.isWithinRedLine == item.isWithinRedLine && newStats.value >= 0) {
|
if (
|
||||||
item.value = newStats.value
|
item.label.includes(newStats.riskLevel) &&
|
||||||
item.show = true
|
newStats.isWithinRedLine == item.isWithinRedLine &&
|
||||||
|
newStats.value >= 0
|
||||||
|
) {
|
||||||
|
item.value = newStats.value;
|
||||||
|
item.show = true;
|
||||||
}
|
}
|
||||||
if (item.show) {
|
if (item.show) {
|
||||||
hazardStatsShowArr.value.push(item)
|
hazardStatsShowArr.value.push(item);
|
||||||
hazardStats.value[6].show = true
|
hazardStats.value[6].show = true;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
hazardStats.value[6].value =
|
hazardStats.value[6].value =
|
||||||
hazardStats.value[0].value +
|
hazardStats.value[0].value +
|
||||||
@ -127,64 +134,51 @@ watch(
|
|||||||
hazardStats.value[2].value +
|
hazardStats.value[2].value +
|
||||||
hazardStats.value[3].value +
|
hazardStats.value[3].value +
|
||||||
hazardStats.value[4].value +
|
hazardStats.value[4].value +
|
||||||
hazardStats.value[5].value
|
hazardStats.value[5].value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true },
|
{ immediate: true, deep: true }
|
||||||
)
|
);
|
||||||
|
|
||||||
// 设置日期时间为当天的23:59:59
|
// 设置日期时间为当天的23:59:59
|
||||||
const setEndOfDay = (date) => {
|
const setEndOfDay = date => {
|
||||||
if (!date) return date
|
if (!date) return date;
|
||||||
const d = new Date(date)
|
const d = new Date(date);
|
||||||
d.setHours(23, 59, 59, 999)
|
d.setHours(23, 59, 59, 999);
|
||||||
return d
|
return d;
|
||||||
}
|
};
|
||||||
// 点击本轮
|
// 点击本轮
|
||||||
const handleDateRangeClick = (type) => {
|
const handleDateRangeClick = () => {
|
||||||
const now = new Date()
|
dateRange.value = [];
|
||||||
if (type === 'total') {
|
|
||||||
// 今年1月1号 00:00:00 到今年年底 23:59:59
|
|
||||||
const startOfYear = new Date(now.getFullYear(), 0, 1, 0, 0, 0, 0)
|
|
||||||
const endOfYear = new Date(now.getFullYear(), 11, 31, 23, 59, 59, 999)
|
|
||||||
dateRange.value = [startOfYear, endOfYear]
|
|
||||||
} else if (type === 'today') {
|
|
||||||
// 今天 00:00:00 到 23:59:59
|
|
||||||
const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0)
|
|
||||||
const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999)
|
|
||||||
dateRange.value = [startOfDay, endOfDay]
|
|
||||||
} else {
|
|
||||||
dateRange.value = []
|
|
||||||
}
|
|
||||||
// triggerRefreshLeftData();
|
// triggerRefreshLeftData();
|
||||||
// 不需要手动 emit,watch 会监听 dateRange 变化并自动 emit
|
// 不需要手动 emit,watch 会监听 dateRange 变化并自动 emit
|
||||||
}
|
};
|
||||||
// 监听 dateRange 变化
|
// 监听 dateRange 变化
|
||||||
watch(
|
watch(
|
||||||
dateRange,
|
dateRange,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 只有当值真正发生变化时才触发
|
// 只有当值真正发生变化时才触发
|
||||||
console.log('dateRange 变化:', newVal, oldVal)
|
console.log('dateRange 变化:', newVal, oldVal);
|
||||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||||
console.log('dateRange 发生变化:', newVal)
|
console.log('dateRange 发生变化:', newVal);
|
||||||
// 如果有结束日期,将其设置为当天的23:59:59
|
// 如果有结束日期,将其设置为当天的23:59:59
|
||||||
if (newVal && newVal.length === 2 && newVal[1]) {
|
if (newVal && newVal.length === 2 && newVal[1]) {
|
||||||
newVal[1] = setEndOfDay(newVal[1])
|
newVal[1] = setEndOfDay(newVal[1]);
|
||||||
}
|
}
|
||||||
// 触发兄弟组件刷新
|
// 触发兄弟组件刷新
|
||||||
// if (triggerRefreshLeftData) {
|
// if (triggerRefreshLeftData) {
|
||||||
// triggerRefreshLeftData();
|
// triggerRefreshLeftData();
|
||||||
// }
|
// }
|
||||||
// 向父组件传递时间范围
|
// 向父组件传递时间范围
|
||||||
emit('dateRangeChange', newVal)
|
emit('dateRangeChange', newVal);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true }
|
||||||
)
|
);
|
||||||
|
|
||||||
const handleAIClick = () => {
|
const handleAIClick = () => {
|
||||||
emit('openAIResult')
|
emit('openAIResult');
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取风险等级统计数据
|
// 获取风险等级统计数据
|
||||||
const fetchRiskLevelCount = async () => {
|
const fetchRiskLevelCount = async () => {
|
||||||
@ -192,35 +186,35 @@ const fetchRiskLevelCount = async () => {
|
|||||||
const res = await request({
|
const res = await request({
|
||||||
url: '/snow-ops-platform/risk-point/risk-level-count',
|
url: '/snow-ops-platform/risk-point/risk-level-count',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
});
|
||||||
console.log('风险等级统计数据:', res)
|
console.log('风险等级统计数据:', res);
|
||||||
if (res.code === '00000' && res.data) {
|
if (res.code === '00000' && res.data) {
|
||||||
// 更新路段统计数据
|
// 更新路段统计数据
|
||||||
const data = res.data
|
const data = res.data;
|
||||||
let roadTotal = 0
|
let roadTotal = 0;
|
||||||
roadStats.value.forEach((item) => {
|
roadStats.value.forEach(item => {
|
||||||
// 重置值为0
|
// 重置值为0
|
||||||
item.value = 0
|
item.value = 0;
|
||||||
// 查找匹配的数据
|
// 查找匹配的数据
|
||||||
const matchedData = data.find((d) => item.label.includes(d.level))
|
const matchedData = data.find(d => item.label.includes(d.level));
|
||||||
if (matchedData) {
|
if (matchedData) {
|
||||||
item.value = Number(matchedData.count)
|
item.value = Number(matchedData.count);
|
||||||
roadTotal += Number(matchedData.count)
|
roadTotal += Number(matchedData.count);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
// 更新风险点总数
|
// 更新风险点总数
|
||||||
roadStats.value[4].value = roadTotal
|
roadStats.value[4].value = roadTotal;
|
||||||
console.log('更新后的roadStats:', roadStats.value)
|
console.log('更新后的roadStats:', roadStats.value);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取风险等级统计数据失败:', error)
|
console.error('获取风险等级统计数据失败:', error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 组件挂载时获取数据
|
// 组件挂载时获取数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchRiskLevelCount()
|
fetchRiskLevelCount();
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user