Merge remote-tracking branch 'origin/main' into zxy

This commit is contained in:
2026-06-17 22:07:09 +08:00
45 changed files with 677 additions and 56 deletions
+14 -4
View File
@@ -16,7 +16,11 @@
</header>
<div class="content">
<table class="table">
<tr v-for="(tableData, index) in tableDatas" :key="index">
<tr
v-for="(tableData, index) in tableDatas"
:key="index"
:style="tableData.styles || {}"
>
<td class="label">{{ tableData.title }}</td>
<td>{{ tableData.content }}</td>
</tr>
@@ -33,6 +37,7 @@
title: string;
data: Record<string, string>;
field: Record<string, string>;
style?: Record<string, Record<string, string>>;
offsetX: number;
offsetY: number;
}>();
@@ -43,7 +48,8 @@
const newOffsetX = ref(props.offsetX);
const newOffsetY = ref(props.offsetY);
const tableDatas: Ref<{ title: string; content: string }[]> = ref([]);
const tableDatas: Ref<{ title: string; content: string; styles?: Record<string, string> }[]> =
ref([]);
onMounted(() => {
// 判断是否超出屏幕,超出就重新定位
@@ -58,10 +64,14 @@
Object.entries(props.data).forEach(([key, value]) => {
// 判断key是不是存在field中,存在就添加到表格数据,不存在则不添加
if (Object.hasOwn(props.field, key) && value) {
tableDatas.value.push({
const rowData: { title: string; content: string; styles?: Record<string, string> } = {
title: props.field[key],
content: value,
});
};
if (props.style && Object.hasOwn(props.style, key)) {
rowData.styles = props.style[key];
}
tableDatas.value.push(rowData);
}
});
});
+3 -1
View File
@@ -40,7 +40,9 @@
polygonStyle: {
fill: true,
fillColor: areasColor[index].withAlpha(areaTransparency),
outline: false,
outline: true,
outlineColor: Color.WHITE,
outlineWidth: 3,
},
},
}));
@@ -14,6 +14,14 @@
"
/>
<!-- 崩塌隐患点 -->
<CollapseComponent
v-if="
statusStore.appLoadingCompleted &&
statusStore.poiLayers.showCollapseHiddenPoint.loading
"
/>
<!-- 泥石流隐患点 -->
<DebrisFlowComponent
v-if="
@@ -57,6 +65,14 @@
"
/>
<!-- 崩塌隐患点 -->
<CollapseComponent
v-if="
statusStore.appLoadingCompleted &&
statusStore.poiLayers.showCollapseHiddenPoint.loading
"
/>
<!-- 泥石流隐患点 -->
<DebrisFlowComponent
v-if="
@@ -81,6 +97,7 @@
import { DisasterType } from '@/types/common/DisasterType.ts';
import RiskPointComponent from '@/component/rain-earthquake/basic/RiskPointComponent.vue';
import LandslideComponent from '@/component/rain-earthquake/basic/LandslideComponent.vue';
import CollapseComponent from '@/component/rain-earthquake/basic/CollapseComponent.vue';
import DebrisFlowComponent from '@/component/rain-earthquake/basic/DebrisFlowComponent.vue';
import WaterLoggingComponent from '@/component/rain-earthquake/basic/WaterLoggingComponent.vue';
import FlashFloodComponent from '@/component/rain-earthquake/basic/FlashFloodComponent.vue';
@@ -0,0 +1,132 @@
<!-- 崩塌隐患点组件 -->
<template>
<div>
<!-- 加载崩塌隐患点 -->
<LoadingPoints
v-if="statusStore.appLoadingCompleted && collapsePoints.length > 0"
:base-points="collapsePoints"
:get-disaster-icon="getDisasterIcon"
:prefix="config.prefix.collapseHiddenPointId"
:is-default="true"
:loading-resource-field="LoadingResource.COLLAPSE_HIDDEN_POINT"
/>
<!-- 显示信息框 -->
<InformationBox
:data="collapsePointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.collapseHiddenPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
:offset-y="offsetY"
:key="loadingInformationStore.collapseHiddenPoint.id"
/>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import { $api } from '@/api/api.ts';
import type { Point } from '@/types/base/Point.ts';
import LoadingPoints from '@/component/common/LoadingPoints.vue';
import config from '@/config/config.json';
import InformationBox from '@/component/common/InformationBox.vue';
import { useStatusStore } from '@/stores/useStatusStore.ts';
import { useLoadingInformationStore } from '@/stores/useLoadingInformation.ts';
import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils.ts';
import { LoadingResource } from '@/types/common/LoadingResourceType.ts';
import { useHiddenPoint } from '@/hooks/rain-earthquake/useHiddenPoint.ts';
import { useLoadingResourceStore } from '@/stores/useLoadingResourceStore.ts';
import {
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const collapsePoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
const { field, style, getDisasterIcon } = useHiddenPoint();
// 信息框相关配置
const offsetX = ref(0);
const offsetY = ref(0);
const collapsePointDetail = ref<Point>();
const informationBoxTitle = ref('');
// 加载崩塌隐患点数据
$api.hiddenDangerSpots
.getBasePoints(HiddenDangerPointTypeMap[PointType.COLLAPSE])
.then((res) => {
collapsePoints.value = res.data;
});
// 监听id变化
watch(
() => loadingInformationStore.collapseHiddenPoint.id,
async (newId: number) => {
if (newId === -1) {
return;
}
// 获取崩塌隐患点数据
const clickObject = loadingInformationStore.clickObject;
if (!clickObject || !clickObject.primitive) {
console.warn('点击对象或图元不存在');
return;
}
const res = await $api.hiddenDangerSpots.getPointDetailById(
loadingInformationStore.collapseHiddenPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
collapsePointDetail.value = res.data;
informationBoxTitle.value = res.data.disasterName || '崩塌隐患点信息';
try {
// 将坐标转换为偏移量
const screenPos = CesiumUtilsSingleton.convertScreenPosition(
clickObject.primitive.position
);
offsetX.value = screenPos.x;
offsetY.value = screenPos.y;
// 显示新的信息框
loadingInformationStore.collapseHiddenPoint.loading = true;
} catch (error) {
throw new Error(`坐标转换失败:${error}`);
}
}
);
// 监听显示隐藏
watch(
() => statusStore.poiLayers.showCollapseHiddenPoint.show,
(newValue: boolean) => {
if (newValue) {
// 显示崩塌隐患点
CesiumUtilsSingleton.batchShowPrimitives(
loadingResourceStore.getLoadingResource(
LoadingResource.COLLAPSE_HIDDEN_POINT
).ids
);
} else {
// 隐藏崩塌隐患点
CesiumUtilsSingleton.batchHidePrimitives(
loadingResourceStore.getLoadingResource(
LoadingResource.COLLAPSE_HIDDEN_POINT
).ids
);
}
}
);
</script>
<style scoped></style>
@@ -15,6 +15,7 @@
<InformationBox
:data="debrisFlowPointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.debrisFlowHiddenPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -41,14 +42,16 @@
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const debrisFlowPoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
const { field, getDisasterIcon } = useHiddenPoint();
const { field, style, getDisasterIcon } = useHiddenPoint();
// 信息框相关配置
const offsetX = ref(0);
@@ -79,7 +82,8 @@
}
const res = await $api.hiddenDangerSpots.getPointDetailById(
loadingInformationStore.debrisFlowHiddenPoint.id
loadingInformationStore.debrisFlowHiddenPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
@@ -15,6 +15,7 @@
<InformationBox
:data="flashFloodPointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.flashFloodHiddenPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -41,14 +42,16 @@
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const flashFloodPoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
const { field, getDisasterIcon } = useHiddenPoint();
const { field, style, getDisasterIcon } = useHiddenPoint();
// 信息框相关配置
const offsetX = ref(0);
@@ -79,7 +82,8 @@
}
const res = await $api.hiddenDangerSpots.getPointDetailById(
loadingInformationStore.flashFloodHiddenPoint.id
loadingInformationStore.flashFloodHiddenPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
@@ -15,6 +15,7 @@
<InformationBox
:data="landslidePointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.landslideHiddenPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -41,14 +42,16 @@
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const landslidePoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
const { field, getDisasterIcon } = useHiddenPoint();
const { field, style, getDisasterIcon } = useHiddenPoint();
// 信息框相关配置
const offsetX = ref(0);
@@ -79,7 +82,8 @@
}
const res = await $api.hiddenDangerSpots.getPointDetailById(
loadingInformationStore.landslideHiddenPoint.id
loadingInformationStore.landslideHiddenPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
@@ -15,6 +15,7 @@
<InformationBox
:data="riskPointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.riskPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -37,12 +38,14 @@
import { useRiskPoint } from '@/hooks/rain-earthquake/useRiskPoint.ts';
import { LoadingResource } from '@/types/common/LoadingResourceType.ts';
import { useLoadingResourceStore } from '@/stores/useLoadingResourceStore.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const riskPoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
// 信息框相关配置
const offsetX = ref(0);
@@ -50,7 +53,7 @@
const riskPointDetail = ref<Point>();
// 获取钩子函数
const { informationBoxTitle, field, getDisasterIcon } = useRiskPoint();
const { informationBoxTitle, field, style, getDisasterIcon } = useRiskPoint();
$api.riskSpots.getBasePoints().then((res) => {
riskPoints.value = res.data;
@@ -72,7 +75,8 @@
}
const res = await $api.riskSpots.getPointDetailById(
loadingInformationStore.riskPoint.id
loadingInformationStore.riskPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
@@ -100,15 +104,13 @@
(newValue: boolean) => {
if (newValue) {
CesiumUtilsSingleton.batchShowPrimitives(
loadingResourceStore.getLoadingResource(
LoadingResource.RISK_POINT
).ids
loadingResourceStore.getLoadingResource(LoadingResource.RISK_POINT)
.ids
);
} else {
CesiumUtilsSingleton.batchHidePrimitives(
loadingResourceStore.getLoadingResource(
LoadingResource.RISK_POINT
).ids
loadingResourceStore.getLoadingResource(LoadingResource.RISK_POINT)
.ids
);
}
}
@@ -3,9 +3,7 @@
<div>
<!-- 加载内涝隐患点 -->
<LoadingPoints
v-if="
statusStore.appLoadingCompleted && waterLoggingPoints.length > 0
"
v-if="statusStore.appLoadingCompleted && waterLoggingPoints.length > 0"
:base-points="waterLoggingPoints"
:get-disaster-icon="getDisasterIcon"
:prefix="config.prefix.waterLoggingHiddenPointId"
@@ -17,6 +15,7 @@
<InformationBox
:data="waterLoggingPointDetail as Record<string, any>"
:field="field"
:style="style"
v-if="loadingInformationStore.waterLoggingHiddenPoint.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -43,14 +42,16 @@
PointType,
HiddenDangerPointTypeMap,
} from '@/types/common/DisasterType.ts';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
const waterLoggingPoints = ref<Point[]>([]);
const statusStore = useStatusStore();
const loadingInformationStore = useLoadingInformationStore();
const loadingResourceStore = useLoadingResourceStore();
const simulationIdStore = useSimulationIdStore();
const { field, getDisasterIcon } = useHiddenPoint();
const { field, style, getDisasterIcon } = useHiddenPoint();
// 信息框相关配置
const offsetX = ref(0);
@@ -81,7 +82,8 @@
}
const res = await $api.hiddenDangerSpots.getPointDetailById(
loadingInformationStore.waterLoggingHiddenPoint.id
loadingInformationStore.waterLoggingHiddenPoint.id,
simulationIdStore.status ? simulationIdStore.id : -1
);
// 更新数据
@@ -15,6 +15,7 @@
<InformationBox
:data="storePointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.bridge.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="dangerousSourcePointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.dangerousSource.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="emergencyShelterPointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.emergencyShelter.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="fireStationPointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.fireStation.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="hospitalPointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.hospital.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -4,18 +4,23 @@
</template>
<script lang="ts" setup>
import { $api } from '@/api/api';
import { useRainstormDeduction } from '@/hooks/rainstorm/useRainstormDeduction';
import { useSimulationIdStore } from '@/stores/useSimulationIdStore';
import { useStatusStore } from '@/stores/useStatusStore';
import { useStepStore } from '@/stores/useStepStore';
import type { ApiResponse } from '@/types/ApiResponse';
import type { RainfallGridResponse } from '@/types/rainstorm/RainfallGridResponse';
import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils';
import { WebSocketService } from '@/utils/request/websocket';
import { Utils } from '@/utils/utils';
import { onMounted, onUnmounted, watch } from 'vue';
let rainfallWsService: WebSocketService | null = null;
const { triggerLayerShowStatus, addGridLayer } = useRainstormDeduction();
const statusStore = useStatusStore();
const stepStore = useStepStore();
const simulationIdStore = useSimulationIdStore();
// 请求降雨栅格数据
const requestRainfallData = () => {
@@ -38,11 +43,33 @@
'/topic/rainfall/grid/messages',
(response) => {
if (response.code === 200 && response.data) {
// 设置步骤为第一步
stepStore.currentStep = 0;
// 显示图层
addGridLayer(response.data);
// 推进到下一步
stepStore.nextStep();
// 进行模型计算
$api.rainfall
.modelDeduction({
disaster_name: `${Utils.formatDate('YYYYMMDDHHmmss')}暴雨自动推演`,
operation_type: '暴雨灾害链自动推演',
})
.then((res) => {
// 进行预警
CesiumUtilsSingleton.addPulseEffect(res.data.list);
// 设置事件id
simulationIdStore.setId(res.data.record_id);
// 推进到下一步
stepStore.nextStep();
// 产出报告
console.log(res);
});
} else {
console.warn('响应错误:', response.message);
}
@@ -15,6 +15,7 @@
<InformationBox
:data="reservoirDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.reservoir.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="schoolDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.school.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="storePointDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.storePoints.loading"
:title="informationBoxTitle"
:offset-x="offsetX"
@@ -15,6 +15,7 @@
<InformationBox
:data="subwayStationDetail as Record<string, any>"
:field="field"
:style="{}"
v-if="loadingInformationStore.subwayStation.loading"
:title="informationBoxTitle"
:offset-x="offsetX"