影响点情况弹窗增加筛选功能,增加巡查路段接口,

This commit is contained in:
fanjia 2026-04-23 17:54:16 +08:00
parent 97e421cf24
commit a3ff5082a6
12 changed files with 242 additions and 95 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

View File

@ -119,6 +119,10 @@ const props = defineProps({
type: Array,
default: () => [],
},
itemFilterForm: {
type: Object,
default: () => {},
},
});
const emit = defineEmits(['update:visible', 'close', 'detail', 'itemdata']);
@ -129,6 +133,15 @@ const filterForm = ref({
type: '',
roadConditionType: '',
});
watch(
() => props.itemFilterForm,
newVal => {
console.log('newVal', newVal);
filterForm.value.roadConditionType = newVal.label.substring(0, newVal.label.length - 1) || '';
currentPage.value = 1;
fetchData();
}
);
//
// index.js
@ -283,16 +296,6 @@ const fetchData = async () => {
}
};
// visible
watch(
() => props.visible,
newVal => {
if (newVal) {
currentPage.value = 1;
fetchData();
}
}
);
watch(
() => filterForm.value,
newVal => {

View File

@ -180,6 +180,7 @@ watch(
margin-bottom: 16px;
.filter-row {
width: 700px;
display: flex;
gap: 12px;
flex-wrap: wrap;

View File

@ -58,7 +58,7 @@
<div class="info-item">
<span class="info-dot"></span>
<span class="info-label">发现时间</span>
<span class="info-value">{{ basicInfo.discoverTime }}</span>
<span class="info-value">{{ basicInfo.findTime }}</span>
</div>
</div>
</div>
@ -177,7 +177,17 @@ const basicInfo = ref({
riskDesc: '',
discoverTime: '',
});
watch(
() => props.item,
newVal => {
if (newVal) {
//
getAffectedObjectTypeId(props.item);
console.log(basicInfo.value);
console.log(props.item);
}
}
);
//
const photoList = ref([]);
@ -363,13 +373,13 @@ const getAffectedObjectTypeId = data => {
} else if (pointType === '路段') {
// -
basicInfo.value = {
district: data.GL1_QDMC || '-', //
level: data.GL1_JSDJ || '未评定', //
levelClass: data.GL1_JSDJ, //
roadCode: data.GL1_LXBH || '-', // 线
location: `${data.GL1_QDMC || '-'} - ${data.GL1_ZDMC || '-'}`, //
riskDesc: '-', //
discoverTime: '-', //
district: data.rawData.GL1_QXMC || '-', //
level: data.rawData.GL1_FXDJ || '未评定', //
levelClass: data.rawData.GL1_FXDJ, //
roadCode: data.rawData.GL1_LXBH || '-', // 线
location: data.pointLocation, //
riskDesc: data.rawData.GL1_FXMS || '-', //
discoverTime: data.rawData.GL1_SBSJ || '-', //
};
// -
@ -435,7 +445,7 @@ watch(
newVal => {
if (newVal) {
//
getAffectedObjectDetail();
// getAffectedObjectDetail();
}
}
);

View File

@ -42,22 +42,6 @@
<!-- 筛选区域 -->
<template #filter>
<div class="filter-row">
<div class="filter-item">
<el-select
:teleported="false"
v-model="filterForm.pointType"
size="small"
placeholder="影响点类型"
class="filter-select"
>
<el-option
v-for="option in pointTypeOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-select>
</div>
<div class="filter-item">
<el-select
:teleported="false"
@ -65,6 +49,8 @@
size="small"
placeholder="影响点等级"
class="filter-select"
clearable
@change="handleFilterChange"
>
<el-option
v-for="option in pointLevelOptions"
@ -81,9 +67,11 @@
size="small"
placeholder="影响区域"
class="filter-select"
clearable
@change="handleFilterChange"
>
<el-option
v-for="option in regionOptionsWithAll"
v-for="option in regionOptions"
:key="option.value"
:label="option.label"
:value="option.value"
@ -201,7 +189,7 @@
import { ref, computed, watch, onMounted } from 'vue';
import { Close, ArrowLeft, ArrowRight } from '@element-plus/icons-vue';
import { request } from '@/utils/request';
import { pointTypeOptions, pointLevelOptions, regionOptionsWithAll } from '../component/index.js';
import { pointTypeOptions, pointLevelOptions, regionOptions } from '../component/index.js';
import baseDialog from '../component/baseDialog.vue';
import respondedIcon from '../../../assets/xiangying/有回应@2x.png';
@ -478,9 +466,16 @@ const handleCurrentChange = val => {
currentPage.value = val;
fetchData();
};
//
const handleFilterChange = () => {
currentPage.value = 1;
fetchData();
};
//
const getTimeParams = () => {
console.log('原始时间范围:', props.handleImpactItem);
const roadConditionType =
regionOptions.value.find(item => item.value === filterForm.value.region)?.label || '';
return {
// start: `${year}-${month}-01 00:00:00`,
// end: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`,
@ -488,6 +483,8 @@ const getTimeParams = () => {
end: formatDateTime(props.handleImpactItem.dateRange?.[1] || ''),
limit: pageSize.value,
offset: (currentPage.value - 1) * pageSize.value,
roadConditionType: roadConditionType || '',
riskLevel: filterForm.value.pointLevel || '',
};
};
//
@ -512,6 +509,7 @@ const processUnifiedData = (item, type) => {
//
const baseData = {
item,
id: item.id,
//
region:
@ -659,7 +657,15 @@ const processUnifiedData = (item, type) => {
// - 使
region: item.GL1_ZDMC || '-',
// - 使线+
pointLocation: item.GL1_LXMC + item.GL1_LXBH,
pointLocation:
item.GL1_QDZH && item.GL1_ZDZH
? item.GL1_LXMC +
'(k' +
(item.GL1_QDZH + '').replace('.', '+') +
'至k' +
(item.GL1_ZDZH + '').replace('.', '+') +
')'
: item.GL1_LXMC,
// - 使
pointLevel: item.GL1_FXDJ || '',
levelClass: getLevelClass(item.GL1_FXDJ),
@ -825,8 +831,7 @@ watch(
gap: vw(16);
.stat-card {
background: linear-gradient(135deg, rgba(30, 70, 120, 0.6) 0%, rgba(20, 50, 90, 0.8) 100%);
border: vw(2) solid rgba(64, 169, 255, 0.4);
width: 1200px;
text-align: center;
transition: all 0.3s;
cursor: pointer;

View File

@ -15,15 +15,22 @@
<!-- 统计卡片区域 -->
<template #header>
<div class="stats-cards">
<div class="stats-card">
<span class="stats-icon road-icon"></span>
<span class="stats-label">国省道:</span>
<span class="stats-value">{{ nationalRoadMileage }}km</span>
</div>
<div class="stats-card">
<span class="stats-icon rural-icon"></span>
<span class="stats-label">农村公路:</span>
<span class="stats-value">{{ ruralRoadMileage }}km</span>
<div
v-for="(item, index) in mileageData"
:key="index"
@click="handleClick(index, item)"
class="stat-card"
:style="{
backgroundImage: `url(${cardType == index ? selectedIcon : unselectedIcon})`,
backgroundSize: '100% 100%',
backgroundPosition: 'center',
}"
>
<div class="stat-icon"><img :src="item.icon" alt="" /></div>
<div class="stat-content">
<span class="stat-label">{{ item.name }}</span>
<span class="stat-value">{{ item.value }}</span>
</div>
</div>
</div>
</template>
@ -58,6 +65,12 @@
import { ref, watch } from 'vue';
import BaseDialog from '../component/baseDialog.vue';
import { request } from '@/utils/request';
import selectedIcon from '../../../assets/xiangying/选中bg@2x.png';
import unselectedIcon from '../../../assets/xiangying/未选中bg@2x.png';
//
import IconNational from '../../../assets/xiangying/国省道icon.png';
import IconRuralRoad from '../../../assets/xiangying/农村公路icon.png';
const props = defineProps({
visible: {
@ -72,6 +85,23 @@ const emit = defineEmits(['update:visible', 'close']);
const nationalRoadMileage = ref(345);
const ruralRoadMileage = ref(4333);
//
const mileageData = ref([
{ name: '国省道', value: 345, icon: IconNational, type: 'national' },
{ name: '农村公路', value: 4333, icon: IconRuralRoad, type: 'rural' },
]);
//
const cardType = ref('0');
//
const handleClick = (index, item) => {
cardType.value = index + '';
//
currentPage.value = 1;
fetchData();
};
//
const filterForm = ref({
district: '',
@ -157,8 +187,13 @@ const fetchStatsData = async () => {
});
if (res.code === '00000' && res.data) {
nationalRoadMileage.value = res.data.nationalRoadMileage || 345;
ruralRoadMileage.value = res.data.ruralRoadMileage || 4333;
const nationalVal = res.data.nationalRoadMileage || 345;
const ruralVal = res.data.ruralRoadMileage || 4333;
nationalRoadMileage.value = nationalVal;
ruralRoadMileage.value = ruralVal;
// mileageData
mileageData.value[0].value = nationalVal;
mileageData.value[1].value = ruralVal;
}
} catch (error) {
console.error('获取巡查里程统计数据失败:', error);
@ -212,43 +247,47 @@ watch(
.stats-cards {
display: flex;
gap: 16px;
width: 700px;
margin-bottom: 16px;
padding: 0 4px;
.stats-card {
.stat-card {
display: flex;
flex: 1;
align-items: center;
gap: 8px;
padding: 10px 16px;
background: linear-gradient(135deg, rgba(64, 169, 255, 0.15) 0%, rgba(24, 144, 255, 0.1) 100%);
border: 1px solid rgba(64, 169, 255, 0.3);
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
.stats-icon {
width: 20px;
height: 20px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
.stat-icon {
width: 32px;
height: 32px;
&.road-icon {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%2340a9ff"><path d="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21.42-1.42 1.01L3 12v8c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55.45 1 1 1h1c.55 0 1-.45 1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5.67 1.5 1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z"/></svg>');
}
&.rural-icon {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%2340a9ff"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z"/></svg>');
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.stats-label {
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
}
.stat-content {
display: flex;
align-items: center;
gap: 4px;
.stats-value {
font-size: 16px;
font-weight: 600;
color: #40a9ff;
.stat-label {
margin-right: 10px;
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
}
.stat-value {
font-size: 16px;
font-weight: 600;
color: #40a9ff;
}
}
}
}

View File

@ -216,8 +216,9 @@ const headerCellStyle = () => {
const cellStyle = () => {
return {
backgroundColor: '#16334E',
backgroundColor: '#17375E',
color: 'rgba(255, 255, 255, 0.85)',
borderBottom: '2px solid #142D47',
fontSize: '13px',
textAlign: 'center',
padding: '5px 0px',
@ -243,7 +244,7 @@ const cellStyle = () => {
}
.base-dialog {
// width: 80vw;
min-width: 600px;
max-height: 80vh;
position: relative;
background: #16334e;

View File

@ -120,8 +120,10 @@ export const pointTypeOptions = [
// 影响点等级选项
export const pointLevelOptions = [
{ label: '全部', value: '' },
{ label: '一般隐患', value: 'normal' },
{ label: '重大隐患', value: 'serious' },
{ label: '低风险', value: '低风险' },
{ label: '中风险', value: '中风险' },
{ label: '较高风险', value: '较高风险' },
{ label: '高风险', value: '高风险' },
];
// 是否回应选项

View File

@ -48,6 +48,9 @@
@openClearanceSituation="openDialog('clearanceSituation')"
@openControlSituation="openDialog('controlSituation')"
@update:dateRange="updateDateRange"
@openPatrolMileage="openDialog('patrolMileage')"
@openPatrolSituation="openDialog('patrolSituation')"
@update:filterForm="updateFilterForm"
></right>
</div>
<!-- 地图中心 -->
@ -197,6 +200,7 @@
<!-- 管控情况对话框 -->
<clearanceSituationDialog
:itemFilterForm="filterForm"
:dateRange="rightDateRange"
v-model:visible="dialogVisible.clearanceSituation"
@close="closeDialog('clearanceSituation')"
@ -263,6 +267,18 @@
v-model:visible="dialogVisible.imageInspection"
@close="closeDialog('imageInspection')"
/>
<!-- 巡查里程对话框 -->
<patrolMileageDialog
v-model:visible="dialogVisible.patrolMileage"
@close="closeDialog('patrolMileage')"
/>
<!-- 巡查情况对话框 -->
<patrolSituationDialog
v-model:visible="dialogVisible.patrolSituation"
@close="closeDialog('patrolSituation')"
/>
</div>
</div>
</template>
@ -308,6 +324,8 @@ import tongnanProjectPersonDialog from './Dialog/tongnanProjectPersonDialog.vue'
import hazardPointSituationDialog from './Dialog/hazardPointSituationDialog.vue';
import offlineHelpDialog from './Dialog/offlineHelpDialog.vue';
import imageInspectionDialog from './Dialog/imageInspectionDialog.vue';
import patrolMileageDialog from './Dialog/patrolMileageDialog.vue';
import patrolSituationDialog from './Dialog/patrolSituationDialog.vue';
import './component/el-select.scss';
import './component/date-picker-theme.scss';
@ -338,6 +356,8 @@ const dialogVisible = ref({
hazardPointSituation: false,
offlineHelp: false,
imageInspection: false,
patrolMileage: false,
patrolSituation: false,
});
const activeitem = ref({});
@ -508,6 +528,11 @@ const updateDateRange = range => {
console.log('更新日期范围:', range);
rightDateRange.value = range;
};
const filterForm = ref({});
const updateFilterForm = item => {
console.log('更新筛选表单:', item);
filterForm.value = item;
};
//
const confirmConfig = ref({
@ -529,7 +554,7 @@ const allCountyData = ref({});
const handleDistrictClick = item => {
console.log('区县点击:', item);
allCountyData.value = item;
if (item.data.roadType == 'national') {
if (item.data.roadType == 'national') {
//
openDialog('tongnanTeam');
} else if (item.data.roadType == 'rural') {

View File

@ -680,8 +680,9 @@ const getBarHeight = value => {
if (!actualValue || actualValue == 0) return '0';
// 10%100%
const height = (actualValue / totalValue.value) * 200;
// 5%
return Math.min(100, Math.max(10, Math.round(height)));
// 3%
// 100% 3%
return Math.min(100, Math.max(3, Math.round(height)));
};
const handleAIClick = () => {
emit('openAIResult');

View File

@ -48,6 +48,7 @@
<div class="control-label">{{ item.label }}</div>
</div>
</div>
<div style="width: 10px"></div>
<div class="control-grid">
@ -68,18 +69,18 @@
</div>
<!-- 巡查公路里程 -->
<div class="patrol-section">
<div class="patrol-section clickable">
<div class="patrol-header display jc_sb ai_center">
<div>
<div @click="handlePatrolClick" style="cursor: pointer;">
<span class="patrol-title">巡查公路里程</span>
<span class="patrol-mileage ml_10">234882km</span>
<span class="patrol-mileage ml_10">{{ roadInspectionMileage }}km</span>
</div>
<div>
<span class="patrol-title">巡查项目数</span>
<span class="patrol-mileage ml_10">6</span>
<span class="patrol-mileage ml_10">0</span>
</div>
</div>
<div class="patrol-grid">
<div class="patrol-grid" style="cursor: pointer;" @click="handlePatrolSituationClick">
<div v-for="(item, index) in patrolData" :key="index" class="patrol-item">
<div class="patrol-value">{{ item.value }}</div>
<div class="patrol-label">{{ item.label }}</div>
@ -220,6 +221,9 @@ const emit = defineEmits([
'openControlSituation',
'openResourceDetail',
'update:dateRange',
'openPatrolMileage',
'openPatrolSituation',
'update:filterForm',
]);
//
@ -533,6 +537,7 @@ const handleControlClick = item => {
) {
emit('openClearanceSituation');
emit('update:dateRange', getdateRange.value || []);
emit('update:filterForm', item || {});
} else if (item.label === '停工项目数' || item.label === '关闭驻地数') {
emit('openControlSituation');
}
@ -544,6 +549,16 @@ const handleBlockClick = () => {
emit('update:dateRange', dateRange.value);
};
//
const handlePatrolClick = () => {
emit('openPatrolMileage');
};
//
const handlePatrolSituationClick = () => {
emit('openPatrolSituation');
};
//
const dateRange = ref([]);
@ -630,13 +645,57 @@ const getAffectedCountByProject = async () => {
};
//
const patrolData = [
{ label: '巡查路段数', value: '2' },
{ label: '巡查桥梁数', value: '1' },
{ label: '巡查边坡数', value: '6' },
{ label: '巡查隧道数', value: '10' },
{ label: '发现隐患数', value: '6' },
];
const patrolData = ref([
{ label: '巡查路段数', value: '0', key: 'roadSectionInspectionCount' },
{ label: '巡查桥梁数', value: '0', key: 'bridgeInspectionCount' },
{ label: '巡查边坡数', value: '0', key: 'slopeInspectionCount' },
{ label: '巡查隧道数', value: '0', key: 'tunnelInspectionCount' },
{ label: '发现隐患数', value: '0', key: 'hiddenDangerCount' },
]);
//
const roadInspectionMileage = ref('0');
//
const getInspectionStats = async () => {
try {
let params = {
start: '',
end: '',
};
if (getdateRange.value && getdateRange.value.length === 2) {
params.start = formatDateTime(getdateRange.value[0]);
params.end = formatDateTime(getdateRange.value[1]);
}
const res = await request({
url: '/snow-ops-platform/yhWgxc/weather-warning/inspection-stats',
method: 'GET',
params: params,
});
console.log('巡查统计数据:', res);
if (res.code == '00000' && res.data) {
const data = res.data;
//
roadInspectionMileage.value = data.roadInspectionMileage || '0';
// patrolDatavalue
patrolData.value.forEach(item => {
if (item.key === 'roadSectionInspectionCount') {
item.value = data.roadSectionInspectionCount || '0';
} else if (item.key === 'bridgeInspectionCount') {
item.value = data.bridgeInspectionCount || '0';
} else if (item.key === 'slopeInspectionCount') {
item.value = data.slopeInspectionCount || '0';
} else if (item.key === 'tunnelInspectionCount') {
item.value = data.tunnelInspectionCount || '0';
} else if (item.key === 'hiddenDangerCount') {
item.value = data.hiddenDangerCount || '0';
}
});
}
} catch (error) {
console.error('获取巡查统计数据失败:', error);
}
};
//
const rescueData = ref([
@ -696,6 +755,7 @@ const init = () => {
getRescueInputStats(); //
getDisasterStats(); //
getInspectionStats(); //
};
//