<template>
|
<div class="real-time-simulation">
|
<div class="left-top">
|
<span>实时模拟</span>
|
<span class="clickable-text" @click="toggleDetails">{{ isCollapsed ? '展开' : '收起' }}</span>
|
</div>
|
<div class="details" :class="{ hidden: isCollapsed }">
|
<div class="input-group">
|
<div class="input-item">
|
<label>雨量数据:</label>
|
<el-select v-model="selectedRainfall" placeholder="请选择" popper-class="mySelectStyle">
|
<el-option
|
v-for="item in rainfallData"
|
:key="item.id"
|
:label="item.name"
|
:value="item.id"
|
></el-option>
|
</el-select>
|
</div>
|
</div>
|
<div class="table-container">
|
<div class="table-row" v-for="(item, index) in filteredTableData" :key="index">
|
<input type="checkbox" v-model="item.selected" />
|
<span>{{ item.name }}</span>
|
</div>
|
</div>
|
<div style="margin-top: 10px;">
|
<label>仿真参数:</label>
|
<div style="width: 100%; height: 60px; background-color: #fff;"></div>
|
</div>
|
</div>
|
<div class="buttons">
|
<el-button type="primary" @click="openSaveDialog">保存方案</el-button>
|
<el-button type="success" @click="startPlay">开始模拟</el-button>
|
<el-button type="success" @click="futurePredictions">未来预测</el-button>
|
</div>
|
|
<!-- 保存方案对话框 -->
|
<el-dialog
|
v-model="saveDialogVisible"
|
title="保存方案"
|
width="50%"
|
:before-close="handleClose"
|
custom-class="custom-dialog"
|
>
|
<div class="dialog-content">
|
<p><strong>所选重点沟:</strong>{{ props.selectedArea }}</p>
|
<p><strong>模拟类型:</strong>实时模拟</p>
|
<p><strong>雨量数据类型:</strong>{{ selectedRainfallName }}</p>
|
<p><strong>设备信息:</strong></p>
|
<ul>
|
<li v-for="item in selectedDevices" :key="item.id">{{ item.name }}</li>
|
</ul>
|
</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="saveDialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="confirmSave">确定保存</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, watch, defineProps, computed, inject } from 'vue';
|
import { ElMessage } from 'element-plus';
|
import { initeWaterPrimitiveView } from "@/utils/water";
|
import { useSimStore } from "@/store/simulation.js"; // 引入 Store
|
|
// 获取 Store 实例
|
const simStore = useSimStore();
|
|
// 注入模拟操作方法
|
const { startSimulate, endSimulate } = inject("simulateActions");
|
|
function startPlay() {
|
const selectedItems = filteredTableData.value.filter(item => item.selected);
|
if (selectedItems.length > 0) {
|
console.log('选中的项:', selectedItems.map(item => item.name));
|
} else {
|
console.log('未选中任何项');
|
}
|
console.log('当前选中的区域:', props.selectedArea);
|
console.log('当前选中的雨量数据:', selectedRainfall.value);
|
initeWaterPrimitiveView();
|
startSimulate();
|
}
|
|
// 工具函数:深拷贝并设置默认选中状态
|
function deepCloneAndSetSelected(data) {
|
const newData = {};
|
for (const key in data) {
|
newData[key] = data[key].map(item => ({ ...item, selected: true }));
|
}
|
return newData;
|
}
|
|
// 接收父组件传递的 props
|
const props = defineProps({
|
selectedArea: {
|
type: String,
|
required: true
|
}
|
});
|
|
// 子组件内部状态
|
const rainfallData = ref([]); // 雨量数据
|
const tableData = ref({}); // 表格数据(按雨量数据分组)
|
const selectedRainfall = ref(''); // 当前选中的雨量数据
|
const isCollapsed = ref(false); // 控制展开/收起状态
|
const saveDialogVisible = ref(false); // 控制保存方案对话框显示状态
|
|
// 模拟不同区域的数据
|
const areaDataMap = {
|
孙胡沟: {
|
rainfallData: [
|
{ id: '1', name: '气象实时数据 - 孙胡沟' },
|
{ id: '2', name: '雨量计实时数据 - 孙胡沟' }
|
],
|
tableData: {
|
'1': [
|
{ id: '001', name: '孙胡沟气象站001' },
|
{ id: '002', name: '孙胡沟气象站002' }
|
],
|
'2': [
|
{ id: '003', name: '孙胡沟雨量计003' },
|
{ id: '004', name: '孙胡沟雨量计004' }
|
]
|
}
|
},
|
鱼水洞后沟: {
|
rainfallData: [
|
{ id: '1', name: '气象实时数据 - 鱼水洞后沟' },
|
{ id: '2', name: '雨量计实时数据 - 鱼水洞后沟' }
|
],
|
tableData: {
|
'1': [
|
{ id: '005', name: '鱼水洞后沟气象站005' },
|
{ id: '006', name: '鱼水洞后沟气象站006' }
|
],
|
'2': [
|
{ id: '007', name: '鱼水洞后沟雨量计007' },
|
{ id: '008', name: '鱼水洞后沟雨量计008' }
|
]
|
}
|
},
|
于家西沟: {
|
rainfallData: [
|
{ id: '1', name: '气象实时数据 - 于家西沟' },
|
{ id: '2', name: '雨量计实时数据 - 于家西沟' }
|
],
|
tableData: {
|
'1': [
|
{ id: '009', name: '于家西沟气象站009' },
|
{ id: '010', name: '于家西沟气象站010' }
|
],
|
'2': [
|
{ id: '011', name: '于家西沟雨量计011' },
|
{ id: '012', name: '于家西沟雨量计012' }
|
]
|
}
|
}
|
};
|
|
// 根据 selectedArea 更新数据
|
watch(
|
() => props.selectedArea,
|
(newArea) => {
|
if (areaDataMap[newArea]) {
|
rainfallData.value = areaDataMap[newArea].rainfallData;
|
// 使用深拷贝设置默认选中状态
|
tableData.value = deepCloneAndSetSelected(areaDataMap[newArea].tableData);
|
selectedRainfall.value = ''; // 清空选中的雨量数据
|
} else {
|
rainfallData.value = [];
|
tableData.value = {};
|
selectedRainfall.value = '';
|
}
|
},
|
{ immediate: true } // 立即执行一次,确保初始数据正确
|
);
|
|
// 动态计算表格数据
|
const filteredTableData = computed(() => {
|
return selectedRainfall.value && tableData.value[selectedRainfall.value]
|
? tableData.value[selectedRainfall.value]
|
: [];
|
});
|
|
// 获取当前选中的雨量数据名称
|
const selectedRainfallName = computed(() => {
|
const selected = rainfallData.value.find(item => item.id === selectedRainfall.value);
|
return selected ? selected.name : '';
|
});
|
|
// 获取当前选中的设备信息
|
const selectedDevices = computed(() => {
|
return filteredTableData.value.filter(item => item.selected);
|
});
|
|
// 打开保存方案对话框
|
const openSaveDialog = () => {
|
if (!props.selectedArea || !selectedRainfall.value || selectedDevices.value.length === 0) {
|
ElMessage.warning('请先选择区域、雨量数据并勾选设备');
|
return;
|
}
|
saveDialogVisible.value = true;
|
};
|
|
// 关闭保存方案对话框
|
const handleClose = () => {
|
saveDialogVisible.value = false;
|
};
|
|
// 确认保存
|
const confirmSave = () => {
|
// 构造新的方案对象
|
const newScheme = {
|
id: Date.now().toString(), // 唯一 ID
|
area: props.selectedArea, // 区域
|
name: selectedRainfallName.value, // 方案名称(雨量数据类型)
|
createTime: new Date().toISOString(), // 创建时间
|
taskStatus:1, // 初始状态为未开始
|
rainfallType: selectedRainfallName.value, // 雨量数据类型
|
devices: selectedDevices.value.map((item) => item.name), // 设备信息
|
};
|
|
// 调用 Store 的方法添加方案
|
simStore.addSchemCard(newScheme);
|
|
console.log("保存方案成功", newScheme);
|
ElMessage.success("方案已保存");
|
|
// 关闭对话框
|
saveDialogVisible.value = false;
|
};
|
|
const toggleDetails = () => {
|
isCollapsed.value = !isCollapsed.value;
|
};
|
|
const futurePredictions = () => {
|
console.log('未来预测按钮被点击');
|
};
|
</script>
|
|
<style scoped>
|
.custom-dialog {
|
z-index: 3000 !important;
|
}
|
.real-time-simulation {
|
margin-bottom: 20px;
|
}
|
|
.clickable-text {
|
margin-left: 160px;
|
cursor: pointer;
|
font-size: 14px;
|
color: #61f7d4;
|
}
|
|
.details {
|
margin-top: 10px;
|
transition: height 0.3s ease, opacity 0.3s ease;
|
overflow: hidden;
|
}
|
|
.hidden {
|
height: 0;
|
opacity: 0;
|
}
|
|
.input-group {
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
}
|
|
.input-item {
|
display: flex;
|
align-items: center;
|
}
|
|
label {
|
text-align: left;
|
white-space: nowrap;
|
margin-right: 10px;
|
}
|
|
.el-select {
|
flex: 4;
|
text-align: left;
|
margin-bottom: 10px;
|
}
|
|
.table-container {
|
font-size: 12px;
|
height: 120px;
|
overflow-y: auto;
|
border: 1px solid #ddd;
|
border-radius: 4px;
|
padding: 5px;
|
}
|
|
.table-row {
|
display: flex;
|
justify-content: space-between;
|
padding: 5px 0;
|
border-bottom: 1px solid #ddd;
|
}
|
|
.table-row:last-child {
|
border-bottom: none;
|
}
|
|
.table-row span {
|
flex: 1;
|
text-align: left;
|
}
|
|
.table-row input[type="checkbox"] {
|
margin-right: 10px;
|
}
|
|
.buttons {
|
margin-top: 20px;
|
display: flex;
|
gap: 10px;
|
}
|
|
.el-button {
|
flex: 1;
|
}
|
</style>
|