<template>
|
<div class="history-simulation">
|
<div class="left-top">
|
<span>预测模拟</span>
|
<span class="clickable-text" @click="toggleDetails">{{
|
isCollapsed ? "展开" : "收起"
|
}}</span>
|
</div>
|
<el-form
|
:class="{ hidden: isCollapsed }"
|
:model="forms"
|
class="details"
|
label-width="auto"
|
style="max-width: 600px"
|
>
|
<el-form-item label="预测数据:">
|
<el-select
|
v-model="forms.prediction"
|
placeholder="请选择"
|
popper-class="mySelectStyle"
|
>
|
<el-option
|
v-for="item in ForecastData"
|
:key="item.id"
|
:label="item.name"
|
:value="item.name"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="降雨年份:" v-show="forms.prediction == '降雨场次'">
|
<el-select
|
v-model="forms.showRainYears"
|
placeholder="请选择"
|
popper-class="mySelectStyle"
|
@change="changeYear"
|
>
|
<el-option
|
v-for="item in rainYears"
|
:key="item.id"
|
:label="item.label"
|
:value="item.label"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="降雨数据:" v-show="showSelect">
|
<el-select
|
@change="rainFallChange"
|
v-model="forms.showRainFall"
|
placeholder="请选择"
|
popper-class="mySelectStyle"
|
>
|
<el-option
|
v-for="item in rainFall"
|
:key="item.rainfallId"
|
:label="item.rainfallName"
|
:value="item"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="方案名称:">
|
<el-input
|
v-model="forms.name"
|
type="text"
|
placeholder="请输入"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="降雨雨量:">
|
<el-input v-model="forms.rainfall" type="number" placeholder="请输入">
|
<template #append>mm</template></el-input
|
>
|
</el-form-item>
|
<el-form-item label="降雨强度:">
|
<el-input v-model="forms.intensity" type="number" placeholder="请输入">
|
<template #append>mm/h</template></el-input
|
>
|
</el-form-item>
|
<el-form-item label="降雨模式:">
|
<el-select
|
v-model="forms.mode"
|
placeholder="请选择"
|
popper-class="mySelectStyle"
|
>
|
<el-option
|
v-for="item in RainfallPatterns"
|
:key="item.id"
|
:label="item.name"
|
:value="item.name"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="选择时间:" v-show="forms.prediction != '降雨场次'">
|
<el-date-picker
|
v-model="forms.hours"
|
type="datetimerange"
|
start-placeholder="开始时间"
|
end-placeholder="结束时间"
|
format="YYYY-MM-DD HH:mm:ss"
|
date-format="YYYY/MM/DD ddd"
|
time-format="A hh:mm:ss"
|
@change="change"
|
/>
|
</el-form-item>
|
<el-form-item label="选择时间:" v-show="forms.prediction == '降雨场次'">
|
<el-date-picker
|
v-model="forms.hours"
|
type="datetime"
|
placeholder="请选择开始时间"
|
/>
|
</el-form-item>
|
<el-form-item label="预计时长:">
|
<el-input
|
disabled
|
v-model="forms.duration"
|
type="number"
|
placeholder="请输入"
|
><template #append>h</template></el-input
|
>
|
</el-form-item>
|
</el-form>
|
<div class="buttons">
|
<el-button type="primary" @click="openPlan">打开方案</el-button>
|
<el-button type="primary" @click="openSaveDialog">保存方案</el-button>
|
<el-button type="success" @click="startPlay">保存并开始模拟</el-button>
|
</div>
|
</div>
|
</template>
|
<script setup>
|
import { ref, computed, inject, reactive, watch, onMounted } from "vue";
|
import { ElMessage } from "element-plus";
|
import { initeWaterPrimitiveView } from "@/utils/water";
|
import { useSimStore } from "@/store/simulation.js"; // 引入 Store
|
import { SimAPIStore } from "@/store/simAPI";
|
import { getRainfallDataYears } from "@/api/hpApi";
|
import { EventBus } from "@/eventBus"; // 引入事件总线
|
import { getSimStart } from "@/api/trApi";
|
|
onMounted(() => {});
|
|
// 获取 Store 实例
|
const simStore = SimAPIStore();
|
|
// 定义 Props
|
const props = defineProps({
|
selectedArea: {
|
type: Object,
|
required: true,
|
},
|
});
|
|
// 数据绑定
|
const isCollapsed = ref(false); // 控制展开/收起状态
|
const saveDialogVisible = ref(false); // 控制保存方案对话框的显示状态
|
|
// 预测数据选项
|
const ForecastData = [
|
{ id: "1", name: "降雨场次" },
|
{ id: "2", name: "气象数据" },
|
{ id: "3", name: "逐小时预报数据" },
|
{ id: "4", name: "自定义参数" },
|
];
|
|
// 降雨模式选项
|
const RainfallPatterns = [
|
{ id: "1", name: "正态分布" },
|
{ id: "2", name: "平均分布" },
|
{ id: "3", name: "波动平均分布" },
|
{ id: "4", name: "持续上升" },
|
];
|
|
const forms = reactive({
|
rainfall: 50,
|
name: "",
|
intensity: 70,
|
duration: null,
|
prediction: "降雨场次",
|
mode: "正态分布",
|
showRainFall: "",
|
hours: null,
|
type: 1,
|
geom: null, // 先设置为 null 或者其他默认值,
|
showRainYears: "",
|
});
|
|
// 降雨场次选择
|
const rainFall = ref({});
|
// 降雨年份选择
|
const rainYears = [
|
{
|
label: "2024",
|
value: "2024",
|
id: 1,
|
},
|
{
|
label: "2025",
|
value: "2025",
|
id: 2,
|
},
|
];
|
|
const showSelect = ref(false);
|
const changeYear = (val) => {
|
if (val) {
|
showSelect.value = true;
|
}
|
if (val == "2024") {
|
getRainfallDataYears(2024).then((res) => {
|
rainFall.value = res.data.pageData;
|
// console.log(rainFall.value, "2024");
|
});
|
} else if (val == "2025") {
|
getRainfallDataYears(2025).then((res) => {
|
rainFall.value = res.data.pageData;
|
// console.log(rainFall.value, "2025");
|
});
|
}
|
};
|
// 降雨场次选择
|
const rainFallChange = (val) => {
|
console.log(val, "val");
|
const decimalHours = (val.rainfallDuration.match(/(\d+)时(\d+)分/) || [])
|
.slice(1)
|
.reduce((acc, curr, i) => acc + parseInt(curr, 10) / (i === 0 ? 1 : 60), 0)
|
.toFixed(1);
|
// console.log(parseFloat(decimalHours)); // 输出: 2.6
|
forms.duration = decimalHours;
|
forms.intensity = val.rainIntensityHour;
|
forms.rainfall = val.rainfallTotalValue;
|
};
|
|
// 切换详情显示
|
const toggleDetails = () => {
|
isCollapsed.value = !isCollapsed.value;
|
};
|
|
const { calculateHoursDifference } = inject("calculateHours");
|
|
const change = (val) => {
|
forms.duration = calculateHoursDifference(val);
|
};
|
|
const resetForm = () => {
|
forms.rainfall = 50;
|
forms.name = "";
|
forms.intensity = 70;
|
forms.duration = null;
|
forms.prediction = "降雨场次";
|
forms.mode = "正态分布";
|
forms.showRainFall = "";
|
forms.hours = null;
|
forms.type = 1;
|
forms.geom = null; // 先设置为 null 或者其他默认值,
|
};
|
|
// 打开保存方案对话框
|
const openSaveDialog = async () => {
|
// 在 setup 内部更新 geom 的值
|
try {
|
forms.geom = props.selectedArea;
|
await simStore.addSimCheme(forms);
|
// 打印拦挡坝所需要的数据
|
// printDamEntities();
|
resetForm();
|
EventBus.emit("close-selectArea");
|
} catch (err) {}
|
};
|
|
// 注入模拟操作方法
|
const { startSimulate, endSimulate } = inject("simulateActions");
|
|
// 开始模拟
|
async function startPlay() {
|
try {
|
forms.geom = props.selectedArea;
|
// 保存方案
|
const res = await simStore.addSimCheme(forms);
|
const schemeId = res.data?.data?.id;
|
|
if (!schemeId) {
|
ElMessage.error("方案保存失败,未获取到有效 ID");
|
return;
|
}
|
|
// 调用求解器
|
const simStartRes = await getSimStart(schemeId);
|
console.log(simStartRes, "getSimStart 返回结果");
|
|
// 关闭选择区域窗口、初始化视图并开始模拟
|
EventBus.emit("close-selectArea");
|
|
simStore.shouldPoll = true;
|
// 暂时不在此处开始模拟,模拟都在方案列表中进行模拟
|
// initeWaterPrimitiveView();
|
// startSimulate();
|
|
ElMessage.warning({
|
message: "请返回方案列表等待模拟结果!",
|
duration: 10000, // 提示框显示时长,单位为毫秒,默认是3000毫秒
|
});
|
} catch (error) {
|
ElMessage.error("启动模拟失败,请稍后再试");
|
console.log(error);
|
}
|
}
|
|
// 打开方案
|
const openPlan = () => {
|
console.log("打开方案按钮被点击");
|
};
|
// ========================================拦挡坝===============================================================
|
// 获取拦挡坝数据
|
function printDamEntities() {
|
const entities = viewer.entities.values;
|
const damDataList = [];
|
|
for (let i = 0; i < entities.length; i++) {
|
const entity = entities[i];
|
|
if (entity.name && (entity.name === '栏档坝1' || entity.name === '栏档坝2')) {
|
damDataList.push({
|
name: entity.name,
|
position: entity.position?._value,
|
heading: entity.heading?._value ?? entity.heading,
|
pitch: entity.pitch?._value ?? entity.pitch,
|
roll: entity.roll?._value ?? entity.roll,
|
modelScale: entity.model?.scale?._value ?? entity.model?.scale
|
});
|
}
|
}
|
if (damDataList.length > 0) {
|
console.log("【栏档坝实体数据列表】:", damDataList);
|
deleteDamEntitiesAfterDelay();
|
} else {
|
console.log("未找到任何名为 '栏档坝1' 或 '栏档坝2' 的实体");
|
}
|
}
|
// 保存方案后定时清除新建的拦挡坝数据
|
function deleteDamEntitiesAfterDelay() {
|
setTimeout(() => {
|
const entities = Array.from(viewer.entities.values);
|
const damsToDelete = entities.filter(
|
entity => entity.name === '栏档坝1' || entity.name === '栏档坝2'
|
);
|
|
damsToDelete.forEach(entity => {
|
viewer.entities.remove(entity);
|
});
|
|
if (damsToDelete.length > 0) {
|
console.log(`【已删除】共 ${damsToDelete.length} 个栏档坝实体`);
|
} else {
|
console.log("未找到任何可删除的栏档坝实体");
|
}
|
}, 5000);
|
}
|
</script>
|
|
<style lang="less" scoped>
|
.history-simulation {
|
margin-bottom: 20px;
|
}
|
|
.details {
|
width: 100%;
|
height: 100%;
|
padding: 0px 10px 0px 0px;
|
box-sizing: border-box;
|
width: 100%;
|
height: 100%;
|
}
|
|
.hidden {
|
height: 0;
|
opacity: 0;
|
}
|
|
.buttons {
|
margin-top: 10px;
|
margin-right: 10px;
|
display: flex;
|
gap: 10px;
|
}
|
.el-button {
|
flex: 1;
|
}
|
.input-item {
|
display: flex;
|
align-items: center;
|
}
|
|
label {
|
text-align: left;
|
white-space: nowrap;
|
margin-right: 10px;
|
}
|
|
.el-input {
|
flex: 4;
|
}
|
|
span {
|
flex: 1;
|
text-align: left;
|
}
|
|
.el-select {
|
flex: 4;
|
text-align: left;
|
margin-bottom: 10px;
|
}
|
|
.clickable-text {
|
margin-left: 160px;
|
cursor: pointer;
|
font-size: 14px;
|
color: #61f7d4;
|
}
|
|
/* 自定义 Dialog 的 z-index */
|
.custom-dialog {
|
z-index: 3000 !important; /* 确保对话框覆盖其他元素 */
|
}
|
/deep/ .el-input-group__append,
|
.el-input-group__prepend {
|
background-color: #084b42;
|
color: #fff;
|
}
|
/deep/ .el-form-item__label {
|
color: #61f7d4 !important;
|
}
|
/deep/ .el-select {
|
margin-bottom: 0px !important;
|
}
|
/deep/ .el-form-item {
|
margin-top: 10px;
|
}
|
</style>
|