524 lines
22 KiB
Vue
524 lines
22 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 基础组件 -->
|
||
<BasicComponent
|
||
:disaster-type="DisasterType.RAINSTORM"
|
||
:key="route.fullPath"
|
||
/>
|
||
|
||
<!-- 灾害链影响列表组件 -->
|
||
<DisasterChainPointComponent
|
||
v-if="
|
||
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"
|
||
/>
|
||
|
||
<!-- 左侧按钮组件 -->
|
||
<LeftButtonComponent
|
||
v-if="
|
||
statusStore.appLoadingCompleted &&
|
||
statusStore.uiComponents.leftButton.loading
|
||
"
|
||
:button-list="leftButtonInfo"
|
||
/>
|
||
|
||
<!-- 左侧图例组件 -->
|
||
<LeftLegendComponent
|
||
v-if="
|
||
statusStore.appLoadingCompleted &&
|
||
statusStore.uiComponents.leftLegend.loading
|
||
"
|
||
/>
|
||
|
||
<!-- 右侧按钮组件 -->
|
||
<RightButtonComponent
|
||
v-if="
|
||
statusStore.appLoadingCompleted &&
|
||
statusStore.uiComponents.rightButton.loading
|
||
"
|
||
:button-list="rightButtonInfo"
|
||
/>
|
||
|
||
<!-- 控制显示组件 -->
|
||
<ControlShowComponent :constrol-show-list="controlPanel" />
|
||
|
||
<!-- 控制显示详情组件 -->
|
||
<ControlShowDetailComponent />
|
||
|
||
<!-- 功能组件 -->
|
||
<FunctionComponent />
|
||
|
||
<!-- 步骤组件 -->
|
||
<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';
|
||
import DisasterChainPointComponent from '@/component/rain-earthquake/DisasterChainPointComponent.vue';
|
||
import FunctionComponent from '@/component/rain-earthquake/FunctionComponent.vue';
|
||
import LeftButtonComponent from '@/component/rain-earthquake/LeftButtonComponent.vue';
|
||
import LeftLegendComponent from '@/component/rain-earthquake/LeftLegendComponent.vue';
|
||
import RightButtonComponent from '@/component/rain-earthquake/RightButtonComponent.vue';
|
||
import StepComponent from '@/component/rain-earthquake/StepComponent.vue';
|
||
import { useRainDisasterChain } from '@/hooks/rainstorm/useRainDisasterChain';
|
||
import { useAroundAnalysis } from '@/hooks/rain-earthquake/useAroundAnalysis';
|
||
import { InfrastructurePointType } from '@/types/common/InfrastructurePointType';
|
||
import type { AroundAnalysisState } from '@/types/common/useAroundAnalysisType';
|
||
import type { PointResource } from '@/types/common/useAroundAnalysisType';
|
||
import type { XianHiddenDangerSpots } from '@/types/base/XianHiddenDangerSpots';
|
||
import type { XianRiskSpots } from '@/types/base/XianRiskSpots';
|
||
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';
|
||
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();
|
||
|
||
const { leftButtonInfo, rightButtonInfo, controlPanel } =
|
||
useRainDisasterChain();
|
||
|
||
const statusStore = useStatusStore();
|
||
|
||
// 在父组件中创建 useAroundAnalysis 实例,并通过 provide 提供给子组件
|
||
const aroundAnalysisState = useAroundAnalysis();
|
||
provide<AroundAnalysisState>('aroundAnalysisState', aroundAnalysisState);
|
||
|
||
const {
|
||
selectOptions,
|
||
tableColumns,
|
||
tableDatas,
|
||
paginationConfig,
|
||
conditions,
|
||
changeConditions,
|
||
setConditions,
|
||
changeCurrentPage,
|
||
setSelectOptions,
|
||
setTableColumns,
|
||
setTableDatas,
|
||
} = useDisasterChainTable();
|
||
|
||
// 所有数据的总数(所有类型的脉冲点总和)
|
||
const allDataCount = computed(() => {
|
||
return aroundAnalysisState.pulsePoints.value?.length || 0;
|
||
});
|
||
|
||
onBeforeMount(() => {
|
||
// 设置下拉选项
|
||
setSelectOptions([
|
||
{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: '地铁站'},
|
||
]);
|
||
|
||
// 设置表格列配置(默认显示隐患点的列)
|
||
setTableColumns([
|
||
{title: '名称', key: 'disasterName'},
|
||
{title: '位置', key: 'position'},
|
||
{title: '规模等级', key: 'scaleGrade'},
|
||
{title: '险情等级', key: 'riskGrade'},
|
||
]);
|
||
|
||
/**
|
||
* 条件改变执行
|
||
* @param value
|
||
*/
|
||
changeConditions.value = (value: SearchConditions) => {
|
||
setConditions(value);
|
||
|
||
// 根据选择的类型动态改变表格列
|
||
if (value.hiddenPoint === PointType.RISK_AREA) {
|
||
// 风险区:只显示风险区等级
|
||
setTableColumns([
|
||
{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'},
|
||
]);
|
||
} 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'},
|
||
]);
|
||
} else {
|
||
// 隐患点:显示规模等级和险情等级
|
||
setTableColumns([
|
||
{title: '名称', key: 'disasterName'},
|
||
{title: '位置', key: 'position'},
|
||
{title: '规模等级', key: 'scaleGrade'},
|
||
{title: '险情等级', key: 'riskGrade'},
|
||
]);
|
||
}
|
||
};
|
||
|
||
// 监听脉冲点变化和下拉选项变化,过滤并更新表格数据
|
||
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) {
|
||
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;
|
||
} 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);
|
||
} else {
|
||
// 如果没有脉冲点,则清空表格数据
|
||
console.log('清空表格数据');
|
||
setTableDatas([]);
|
||
}
|
||
},
|
||
{ immediate: true, deep: true }
|
||
);
|
||
});
|
||
</script>
|
||
|
||
<style scoped></style> |