Files
xian_vue_new/src/views/home/rainstorm/RainstormView.vue
T

524 lines
22 KiB
Vue
Raw Normal View History

<template>
<div>
2026-04-14 16:00:39 +08:00
<!-- 基础组件 -->
<BasicComponent
:disaster-type="DisasterType.RAINSTORM"
:key="route.fullPath"
/>
2026-04-13 19:27:32 +08:00
2026-04-14 16:00:39 +08:00
<!-- 灾害链影响列表组件 -->
2026-04-13 19:27:32 +08:00
<DisasterChainPointComponent
v-if="
2026-05-07 13:11:15 +08:00
statusStore.appLoadingCompleted &&
statusStore.uiComponents.disasterChainPointShow.loading
"
:select-options="selectOptions"
:table-data-list="tableDatas"
:table-columns="tableColumns"
:page-option="paginationConfig"
:total-data-count="allDataCount"
@change-conditions="changeConditions"
@change-current-page="changeCurrentPage"
2026-04-13 19:27:32 +08:00
/>
2026-04-13 20:55:32 +08:00
2026-04-14 16:00:39 +08:00
<!-- 左侧按钮组件 -->
<LeftButtonComponent
v-if="
2026-05-07 13:11:15 +08:00
statusStore.appLoadingCompleted &&
statusStore.uiComponents.leftButton.loading
"
:button-list="leftButtonInfo"
/>
2026-04-14 16:33:23 +08:00
2026-05-06 17:44:30 +08:00
<!-- 左侧图例组件 -->
<LeftLegendComponent
v-if="
2026-05-07 13:11:15 +08:00
statusStore.appLoadingCompleted &&
statusStore.uiComponents.leftLegend.loading
2026-05-06 17:44:30 +08:00
"
/>
2026-04-14 16:33:23 +08:00
<!-- 右侧按钮组件 -->
<RightButtonComponent
v-if="
2026-05-07 13:11:15 +08:00
statusStore.appLoadingCompleted &&
statusStore.uiComponents.rightButton.loading
"
:button-list="rightButtonInfo"
/>
<!-- 控制显示组件 -->
<ControlShowComponent :constrol-show-list="controlPanel" />
<!-- 控制显示详情组件 -->
<ControlShowDetailComponent />
<!-- 功能组件 -->
<FunctionComponent />
2026-05-06 19:22:10 +08:00
<!-- 步骤组件 -->
<StepComponent />
</div>
</template>
<script setup lang="ts">
import BasicComponent from '@/component/rain-earthquake/BasicComponent.vue';
import ControlShowComponent from '@/component/rain-earthquake/ControlShowComponent.vue';
import ControlShowDetailComponent from '@/component/rain-earthquake/ControlShowDetailComponent.vue';
2026-04-13 19:27:32 +08:00
import DisasterChainPointComponent from '@/component/rain-earthquake/DisasterChainPointComponent.vue';
import FunctionComponent from '@/component/rain-earthquake/FunctionComponent.vue';
2026-04-14 16:00:39 +08:00
import LeftButtonComponent from '@/component/rain-earthquake/LeftButtonComponent.vue';
2026-05-06 17:44:30 +08:00
import LeftLegendComponent from '@/component/rain-earthquake/LeftLegendComponent.vue';
2026-04-14 16:33:23 +08:00
import RightButtonComponent from '@/component/rain-earthquake/RightButtonComponent.vue';
2026-05-06 19:22:10 +08:00
import StepComponent from '@/component/rain-earthquake/StepComponent.vue';
2026-04-13 20:55:32 +08:00
import { useRainDisasterChain } from '@/hooks/rainstorm/useRainDisasterChain';
2026-06-25 22:07:39 +08:00
import { useAroundAnalysis } from '@/hooks/rain-earthquake/useAroundAnalysis';
2026-06-26 13:54:57 +08:00
import { InfrastructurePointType } from '@/types/common/InfrastructurePointType';
2026-06-25 22:07:39 +08:00
import type { AroundAnalysisState } from '@/types/common/useAroundAnalysisType';
import type { PointResource } from '@/types/common/useAroundAnalysisType';
import type { XianHiddenDangerSpots } from '@/types/base/XianHiddenDangerSpots';
2026-06-26 11:16:12 +08:00
import type { XianRiskSpots } from '@/types/base/XianRiskSpots';
2026-06-26 13:54:57 +08:00
import type { XianHospitals } from '@/types/base/XianHospitals';
import type { XianDangerousSource } from '@/types/base/XianDangerousSource';
import type { XianEmergencyShelter } from '@/types/base/XianEmergencyShelter';
import type { XianFirefighter } from '@/types/base/XianFirefighter';
import type { XianStorePoints } from '@/types/base/XianStorePoints';
import type { XianSchool } from '@/types/base/XianSchool';
import type { XianBridge } from '@/types/base/XianBridge';
import type { XianReservoirList } from '@/types/base/XianReservoirList';
import type { XianSubwayStations } from '@/types/base/XianSubwayStations';
2026-06-12 11:20:57 +08:00
import {
useDisasterChainTable,
type SearchConditions,
} from '@/hooks/useDisasterChainTable';
import { useStatusStore } from '@/stores/useStatusStore';
import {
DisasterType,
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import {onBeforeMount, watch, provide, computed} from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
2026-04-13 19:27:32 +08:00
const { leftButtonInfo, rightButtonInfo, controlPanel } =
useRainDisasterChain();
2026-05-07 13:11:15 +08:00
const statusStore = useStatusStore();
2026-06-25 22:07:39 +08:00
// 在父组件中创建 useAroundAnalysis 实例并通过 provide 提供给子组件
const aroundAnalysisState = useAroundAnalysis();
provide<AroundAnalysisState>('aroundAnalysisState', aroundAnalysisState);
2026-06-12 11:20:57 +08:00
const {
selectOptions,
tableColumns,
tableDatas,
paginationConfig,
conditions,
2026-06-12 11:20:57 +08:00
changeConditions,
setConditions,
changeCurrentPage,
setSelectOptions,
setTableColumns,
2026-06-25 22:07:39 +08:00
setTableDatas,
2026-06-12 11:20:57 +08:00
} = useDisasterChainTable();
// 所有数据的总数(所有类型的脉冲点总和)
const allDataCount = computed(() => {
return aroundAnalysisState.pulsePoints.value?.length || 0;
});
onBeforeMount(() => {
2026-06-12 11:20:57 +08:00
// 设置下拉选项
setSelectOptions([
2026-06-26 13:54:57 +08:00
{value: PointType.LANDSLIDE, label: '滑坡'},
{value: PointType.DEBRIS_FLOW, label: '泥石流'},
{value: PointType.WATER_LOGGING, label: '内涝'},
{value: PointType.FLASH_FLOOD, label: '山洪'},
{value: PointType.COLLAPSE, label: '崩塌'},
{value: PointType.RISK_AREA, label: '风险区'},
{value: InfrastructurePointType.HOSPITAL, label: '医院'},
{value: InfrastructurePointType.DANGEROUS_SOURCE, label: '危险源'},
{value: InfrastructurePointType.REFUGEE_SHELTER, label: '避难所'},
{value: InfrastructurePointType.FIRE_STATION, label: '消防站'},
{value: InfrastructurePointType.STORE_POINTS, label: '储备点'},
{value: InfrastructurePointType.SCHOOL, label: '学校'},
{value: InfrastructurePointType.BRIDGE, label: '桥梁'},
{value: InfrastructurePointType.RESERVOIR, label: '水库'},
{value: InfrastructurePointType.SUBWAY, label: '地铁站'},
2026-06-12 11:20:57 +08:00
]);
2026-06-26 11:16:12 +08:00
// 设置表格列配置(默认显示隐患点的列)
2026-06-12 11:20:57 +08:00
setTableColumns([
2026-06-26 13:54:57 +08:00
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '规模等级', key: 'scaleGrade'},
{title: '险情等级', key: 'riskGrade'},
2026-06-12 11:20:57 +08:00
]);
/**
* 条件改变执行
* @param value
*/
changeConditions.value = (value: SearchConditions) => {
setConditions(value);
2026-06-26 11:16:12 +08:00
// 根据选择的类型动态改变表格列
if (value.hiddenPoint === PointType.RISK_AREA) {
// 风险区:只显示风险区等级
setTableColumns([
2026-06-26 13:54:57 +08:00
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '风险区等级', key: 'riskLevel'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.HOSPITAL) {
// 医院:只显示医院等级
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '医院等级', key: 'level'},
2026-06-26 11:16:12 +08:00
]);
} else if (value.hiddenPoint === InfrastructurePointType.DANGEROUS_SOURCE) {
// 危险源:显示危险源等级和安全生产标准化等级
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '危险源等级', key: 'level'},
{title: '安全生产标准化等级', key: 'safeProductLevel'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.REFUGEE_SHELTER) {
// 避难所:显示避难所类型和避难所性质
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '避难所类型', key: 'type'},
{title: '避难所性质', key: 'constructionCategory'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.FIRE_STATION) {
// 消防站:显示队伍类型和消防站类型
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '队伍类型', key: 'teamType'},
{title: '消防站类型', key: 'fireType'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.STORE_POINTS) {
// 储备点:显示分级和所属部门
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '分级', key: 'level'},
{title: '所属部门', key: 'department'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.SCHOOL) {
// 学校:显示学校类型和所属部门
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '学校类型', key: 'schoolType'},
{title: '所属部门', key: 'schoolCreater'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.BRIDGE) {
// 桥梁:显示类型和建成时间
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '类型', key: 'bridgeType'},
{title: '建成时间', key: 'buildTime'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.RESERVOIR) {
// 水库:显示安全状态和净防洪库容
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '安全状态', key: 'safetyStatus'},
{title: '净防洪库容(万m³)', key: 'netFloodCapacity'},
]);
} else if (value.hiddenPoint === InfrastructurePointType.SUBWAY) {
// 地铁站:显示地铁线路和积水深度
setTableColumns([
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '地铁线路', key: 'line'},
{title: '积水深度', key: 'depthOfAccumulatedWater'},
]);
2026-06-26 11:16:12 +08:00
} else {
// 隐患点:显示规模等级和险情等级
setTableColumns([
2026-06-26 13:54:57 +08:00
{title: '名称', key: 'disasterName'},
{title: '位置', key: 'position'},
{title: '规模等级', key: 'scaleGrade'},
{title: '险情等级', key: 'riskGrade'},
2026-06-26 11:16:12 +08:00
]);
}
2026-06-12 11:20:57 +08:00
};
2026-06-25 22:07:39 +08:00
// 监听脉冲点变化和下拉选项变化,过滤并更新表格数据
2026-06-26 13:54:57 +08:00
watch(
[
() => aroundAnalysisState.pulsePoints.value,
() => conditions.value.hiddenPoint,
],
([newPulsePoints, hiddenPointType]: [PointResource[], PointType | InfrastructurePointType]) => {
console.log('=== 脉冲点变化 ===');
console.log('newPulsePoints:', newPulsePoints);
console.log('newPulsePoints.length:', newPulsePoints?.length);
console.log('hiddenPointType:', hiddenPointType);
if (newPulsePoints && newPulsePoints.length > 0) {
// 根据选中的类型过滤
const filteredPoints = newPulsePoints.filter(point => {
// 隐患点过滤
if (point.category === 'hidden-danger') {
const englishType = HiddenDangerPointTypeMap[hiddenPointType as PointType];
return englishType ? point.originalType === englishType : false;
}
// 风险点过滤
if (
hiddenPointType === PointType.RISK_AREA &&
point.category === 'risk-point'
) {
return true;
}
// 基础设施点过滤
const infrastructureMap: Record<string, string> = {
[InfrastructurePointType.HOSPITAL]: 'hospital',
[InfrastructurePointType.DANGEROUS_SOURCE]: 'danger',
[InfrastructurePointType.REFUGEE_SHELTER]: 'shelter',
[InfrastructurePointType.FIRE_STATION]: 'fire',
[InfrastructurePointType.STORE_POINTS]: 'store',
[InfrastructurePointType.SCHOOL]: 'school',
[InfrastructurePointType.BRIDGE]: 'bridge',
[InfrastructurePointType.RESERVOIR]: 'reservoir',
[InfrastructurePointType.SUBWAY]: 'subway',
};
const infraCategory = infrastructureMap[hiddenPointType as InfrastructurePointType];
if (infraCategory && point.category === infraCategory) {
2026-06-26 13:54:57 +08:00
return true;
}
return false;
});
// 根据类型转换数据
const convertedData = filteredPoints.map(point => {
if (point.category === 'risk-point') {
// 风险点数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
riskLevel: String(point.risk_level || '一般'),
lon: point.lon,
lat: point.lat,
} as XianRiskSpots;
} else if (point.category === 'hospital') {
// 医院数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
level: String(point.level || '未知'),
lon: point.lon,
lat: point.lat,
} as XianHospitals;
} else if (point.category === 'danger') {
// 危险源数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
level: String(point.level || '未知'),
safeProductLevel: String(point.safe_product_level || '未知'),
lon: point.lon,
lat: point.lat,
} as XianDangerousSource;
} else if (point.category === 'shelter') {
// 避难所数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
type: String(point.type || '未知'),
constructionCategory: String(point.construction_category || '未知'),
lon: point.lon,
lat: point.lat,
} as XianEmergencyShelter;
} else if (point.category === 'fire') {
// 消防站数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
teamType: String(point.team_type || '未知'),
fireType: String(point.fire_type || '未知'),
lon: point.lon,
lat: point.lat,
} as XianFirefighter;
} else if (point.category === 'store') {
// 储备点数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
level: String(point.level || '未知'),
department: String(point.department || '未知'),
lon: point.lon,
lat: point.lat,
} as XianStorePoints;
} else if (point.category === 'school') {
// 学校数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
schoolType: String(point.school_type || '未知'),
schoolCreater: String(point.school_creater || '未知'),
lon: point.lon,
lat: point.lat,
} as XianSchool;
} else if (point.category === 'bridge') {
// 桥梁数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
bridgeType: String(point.bridge_type || '未知'),
buildTime: String(point.build_time || '未知'),
lon: point.lon,
lat: point.lat,
} as XianBridge;
} else if (point.category === 'reservoir') {
// 水库数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
safetyStatus: String(point.safety_status || '未知'),
netFloodCapacity: String(point.net_flood_capacity || '未知'),
lon: point.lon,
lat: point.lat,
} as XianReservoirList;
} else if (point.category === 'subway') {
// 地铁站数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
line: String(point.line || '未知'),
depthOfAccumulatedWater: String(point.depth_of_accumulated_water || '未知'),
lon: point.lon,
lat: point.lat,
} as XianSubwayStations;
2026-06-26 13:54:57 +08:00
} else {
// 隐患点数据
return {
id:
typeof point.id === 'number'
? point.id
: parseInt(String(point.id), 10),
name: point.value,
disasterName: point.value,
position:
point.lon !== undefined && point.lat !== undefined
? `${point.lon.toFixed(4)}, ${point.lat.toFixed(4)}`
: '未知位置',
scaleGrade: String(point.scale_grade || '未知'),
riskGrade: String(point.risk_grade || '一般'),
lon: point.lon,
lat: point.lat,
fieldCode: String(point.id),
province: '陕西省',
city: '西安市',
county: '',
village: '',
isDelete: 0,
} as XianHiddenDangerSpots;
}
});
console.log('convertedData:', convertedData);
setTableDatas(convertedData);
2026-06-26 11:16:12 +08:00
} else {
2026-06-26 13:54:57 +08:00
// 如果没有脉冲点,则清空表格数据
console.log('清空表格数据');
setTableDatas([]);
2026-06-26 11:16:12 +08:00
}
2026-06-26 13:54:57 +08:00
},
{ immediate: true, deep: true }
);
});
2026-04-13 19:27:32 +08:00
</script>
2026-06-25 22:07:39 +08:00
<style scoped></style>