| | |
| | | |
| | | // 保存方案逻辑 |
| | | const saveScheme = async (forms) => { |
| | | // forms.hours = dayjs(val[0]).format("YYYY-MM-DD HH:mm:ss"); |
| | | if (isLoading.value) { |
| | | ElMessage.warning('正在保存,请稍候...') |
| | | return |
| | |
| | | history: forms.history, |
| | | mode: forms.mode, |
| | | gauges: forms.gauges, |
| | | rainfalls: forms.rainFallList |
| | | rainfalls: forms.rainFallList, |
| | | intensityUnit: forms.intensityUnit |
| | | }) |
| | | } |
| | | console.log(params) |
| | | // const res = await createSimData(params) |
| | | const res = await createSimData(params) |
| | | ElMessage.success('方案保存成功') |
| | | // return res |
| | | return res |
| | | } catch (error) { |
| | | console.error('保存失败:', error) |
| | | ElMessage.error('保存失败: ' + (error.message || '请稍后重试')) |
| | |
| | | |
| | | // 保存方案弹窗 |
| | | const addSimCheme = async (forms) => { |
| | | if (!validateForm(forms)) return |
| | | if (!validateForm(forms)) { |
| | | throw new Error('表单验证未通过'); // 抛出错误,阻止继续执行 |
| | | } |
| | | |
| | | try { |
| | | await ElMessageBox.confirm('确定要保存当前方案吗?', '新建方案', { |
| | |
| | | } else { |
| | | ElMessage.info('已取消保存') |
| | | } |
| | | throw error // 保证外部能捕获到错误 |
| | | } |
| | | } |
| | | |
| | |
| | | }, |
| | | }); |
| | | |
| | | console.log( |
| | | flyToHeight.value, |
| | | "flyToHeight.value flyToHeight.value flyToHeight.value " |
| | | ); |
| | | } |
| | | |
| | | EventBus.on("close-selectArea", () => { |
| | |
| | | <template #append>mm/h</template> |
| | | </el-upload> |
| | | </el-form-item> |
| | | <el-form-item label="雨强单位" v-if="forms.fileList.length !== 0"> |
| | | <el-select |
| | | v-model="forms.intensityUnit" |
| | | placeholder="Select" |
| | | style="max-width: 600px" |
| | | > |
| | | <el-option |
| | | v-for="item in intensityOptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item |
| | | label="行政区域:" |
| | | v-if="simStore.selectTab == '行政区划仿真'" |
| | |
| | | |
| | | const options = reactive([]); |
| | | |
| | | const intensityOptions = ref([ |
| | | { value: "mm/h", label: "mm/h" }, |
| | | { value: "mm/5min", label: "mm/5min" }, |
| | | ]); |
| | | |
| | | // 定义一个方法,用于根据 type 获取区域数据 |
| | | const fetchRegionData = (type) => { |
| | | getRegionData({ type: type }).then((res) => { |
| | |
| | | type: 3, |
| | | rainFallList: [], |
| | | hours: null, |
| | | intensityUnit: "", |
| | | }); |
| | | |
| | | const flyHeight = ref(100000); |
| | |
| | | }; |
| | | |
| | | const addSimCheme = async () => { |
| | | await simStore.addSimCheme(forms); |
| | | resetForm(); |
| | | EventBus.emit("close-selectArea"); |
| | | try { |
| | | await simStore.addSimCheme(forms); |
| | | resetForm(); // 只有在保存成功后才重置表单 |
| | | EventBus.emit("close-selectArea"); |
| | | } catch (error) {} |
| | | }; |
| | | |
| | | // 重置表单 |
| | | const resetForm = () => { |
| | | forms.name = ""; |
| | | forms.geom = ""; |
| | | forms.rainfall = null; |
| | | forms.duration = null; |
| | |
| | | forms.fileList = []; |
| | | forms.rainFallList = []; |
| | | forms.hours = null; |
| | | forms.intensityUnit = ""; |
| | | }; |
| | | |
| | | // 计算属性:获取上传文件的名称列表 |
| | |
| | | })); |
| | | }; |
| | | |
| | | /** |
| | | * 检查时间列是否按升序排列 |
| | | * @param {Array} data - 表格数据 |
| | | * @param {string} timeColumn - 时间列的字段名 |
| | | * @returns {boolean} - 是否按升序排列 |
| | | */ |
| | | const isTimeColumnSorted = (data, timeColumn) => { |
| | | for (let i = 1; i < data.length; i++) { |
| | | const prevTime = parseDateTime(data[i - 1][timeColumn]); |
| | | const currentTime = parseDateTime(data[i][timeColumn]); |
| | | |
| | | // 如果前一个时间 > 当前时间,说明不是升序 |
| | | if (prevTime > currentTime) { |
| | | console.error(`时间乱序:第 ${i} 行`, { |
| | | prevTime: new Date(prevTime), |
| | | currentTime: new Date(currentTime), |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | return true; // 所有时间都按升序排列 |
| | | }; |
| | | |
| | | /** |
| | | * 从表头提取单位(如 "小时雨强mm/h" → "mm/h") |
| | | * @param {string} header - 表头字符串 |
| | | * @returns {string} - 提取的单位(如 "mm/h"),默认返回空字符串 |
| | | */ |
| | | const extractUnitFromHeader = (header) => { |
| | | if (!header) return ""; |
| | | |
| | | // 直接匹配 "mm/h"、"m/s" 等常见单位 |
| | | const unitRegex = /(mm\/h|m\/s|mm|℃|%|hPa|km\/h)/; // 根据需要扩展 |
| | | const match = header.match(unitRegex); |
| | | return match ? match[0] : ""; |
| | | }; |
| | | |
| | | // 处理数据 |
| | | const processData = (data) => { |
| | | // 1. 检查数据是否为空 |
| | | if (data.length === 0) { |
| | | ElMessage.warning("文件内容为空!"); |
| | | return; |
| | | } |
| | | |
| | | // 2. 获取表头(第一列是时间列) |
| | | const tableColumns = Object.keys(data[0]); |
| | | const timeColumn = tableColumns[0]; // 假设第一列是时间 |
| | | |
| | | // 3. 校验时间列是否按升序排列 |
| | | if (!isTimeColumnSorted(data, timeColumn)) { |
| | | ElMessage.error("时间列必须按升序排列!"); |
| | | forms.fileList = []; |
| | | return; // 终止处理 |
| | | } |
| | | |
| | | const intensityColumn = tableColumns[1]; // 雨强列(如 "小时雨强(mm/h)") |
| | | console.log(intensityColumn, "intensityColumnintensityColumnintensityColumn"); |
| | | // 3. 提取第二列的单位(如 "(mm/h)" → "mm/h") |
| | | const intensityUnit = extractUnitFromHeader(intensityColumn); |
| | | console.log( |
| | | intensityUnit, |
| | | "intensityUnitintensityUnitintensityUnitintensityUnit" |
| | | ); |
| | | forms.intensityUnit = intensityUnit; // 存储单位(可选) |
| | | |
| | | // 4. 如果校验通过,继续处理数据 |
| | | forms.rainFallList = transformKeys(data); |
| | | console.log(forms.rainFallList, "data"); |
| | | if (data.length === 0) return; |
| | | |
| | | const tableColumns = Object.keys(data[0]); |
| | | |
| | | // 第一列:时间 |
| | | const firstTime = parseDateTime(data[0][tableColumns[0]]); |
| | | const lastTime = parseDateTime(data[data.length - 1][tableColumns[0]]); |
| | | // 5. 计算降雨时长、最大雨强、累计雨量(原逻辑) |
| | | const firstTime = parseDateTime(data[0][timeColumn]); |
| | | const lastTime = parseDateTime(data[data.length - 1][timeColumn]); |
| | | const timeDuration = Math.floor((lastTime - firstTime) / 1000); |
| | | forms.duration = (timeDuration / 3600).toFixed(2); // 更新降雨时长 |
| | | forms.duration = (timeDuration / 3600).toFixed(2); |
| | | |
| | | // 第二列:降雨强度 |
| | | const maxValue = Math.max( |
| | | ...data.map((row) => { |
| | | const value = parseFloat(row[tableColumns[1]]); |
| | | return isNaN(value) ? -Infinity : value; |
| | | }) |
| | | ).toFixed(2); |
| | | forms.intensity = maxValue; // 更新降雨强度 |
| | | forms.intensity = maxValue; |
| | | |
| | | // 第三列:累计降雨量 |
| | | const lastValue = data[data.length - 1][tableColumns[2]]; |
| | | forms.rainfall = lastValue; // 更新降雨量 |
| | | forms.rainfall = lastValue; |
| | | }; |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | // 虚线避险路线 |
| | | // const position1 = [ |
| | | // { |
| | | // x: -2172867.1941179745, |
| | | // y: 4339567.67446477, |
| | | // z: 4125575.4386990573, |
| | | // }, |
| | | // { |
| | | // x: -2172867.1941179745, |
| | | // y: 4339567.67446477, |
| | | // z: 4125575.4386990573, |
| | | // }, |
| | | // { |
| | | // x: -2172700.396781143, |
| | | // y: 4339454.037139385, |
| | | // z: 4125736.906847591, |
| | | // }, |
| | | // { |
| | | // x: -2172744.4001612393, |
| | | // y: 4339361.421455601, |
| | | // z: 4125804.324253885, |
| | | // }, |
| | | // { |
| | | // x: -2172824.3311673277, |
| | | // y: 4339274.56533081, |
| | | // z: 4125844.432999503, |
| | | // }, |
| | | // { |
| | | // x: -2172822.298957661, |
| | | // y: 4339226.700024104, |
| | | // z: 4125896.451233209, |
| | | // }, |
| | | // { |
| | | // x: -2172776.0573917977, |
| | | // y: 4339194.843872361, |
| | | // z: 4125947.9581145854, |
| | | // }, |
| | | // { |
| | | // x: -2172755.2828807314, |
| | | // y: 4339149.410126468, |
| | | // z: 4125995.9286539108, |
| | | // }, |
| | | // { |
| | | // x: -2172660.9533022284, |
| | | // y: 4339085.401362197, |
| | | // z: 4126101.3750262205, |
| | | // }, |
| | | // { |
| | | // x: -2172613.460204307, |
| | | // y: 4339073.342332504, |
| | | // z: 4126134.479399525, |
| | | // }, |
| | | // { |
| | | // x: -2172583.664140033, |
| | | // y: 4339085.533980615, |
| | | // z: 4126140.3272964833, |
| | | // }, |
| | | // { |
| | | // x: -2172348.977405535, |
| | | // y: 4338967.122025027, |
| | | // z: 4126358.7532469626, |
| | | // }, |
| | | // { |
| | | // x: -2172276.019363938, |
| | | // y: 4338943.999121099, |
| | | // z: 4126416.339696519, |
| | | // }, |
| | | // { |
| | | // x: -2172178.064812976, |
| | | // y: 4338928.9482959965, |
| | | // z: 4126475.798078439, |
| | | // }, |
| | | // { |
| | | // x: -2172171.5451145098, |
| | | // y: 4338941.186930828, |
| | | // z: 4126466.425301899, |
| | | // }, |
| | | // { |
| | | // x: -2172177.9565195283, |
| | | // y: 4338940.424956708, |
| | | // z: 4126463.8688932694, |
| | | // }, |
| | | // ]; |
| | | |
| | | |
| | | ///////////////////////////// 流光线避险路线///////////////////////////// |
| | | let pathLayer = null; // 存储创建的图层 |
| | | function showLine() { |
| | |
| | | ///////////////////////////// 箭头版避险路线///////////////////////////// |
| | | |
| | | function timeUpdate(percentage) { |
| | | console.log(percentage, "ppppppppppp"); |
| | | if (percentage > 99.9) { |
| | | if (showDebuffDetail.value) { |
| | | return; |