wangjuncheng
2025-05-29 064150f26aaa34c4cb6da768411f4d784d638b3b
Merge branch 'master' of http://103.135.160.14:9034/r/NslWeb
已修改12个文件
已删除1个文件
575 ■■■■■ 文件已修改
src/api/trApi.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/echartInfo.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/schemeCard.vue 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/LayerTree.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/Message.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/TopographyDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/simAPI.js 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/simulation.js 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/CitySim.vue 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/KGSim.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/KGSimOption/HistorySimulation.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/KGSimOption/PredictiveSimulation.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/KGSimOption/RealTimeSimulation copy.vue 341 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/trApi.js
@@ -24,8 +24,10 @@
// èŽ·å–æ–¹æ¡ˆåˆ—è¡¨
export async function getSimData() {
  try {
    const res = await instance.get("/simu/selectPage");
    return res.data; // è¿”回实际数据(通常 res.data æ‰æ˜¯æŽ¥å£è¿”回的内容)
    const res = await instance.get("/simu/selectPage", {
      params: { pageSize: 100 },
    });
    return res.data;
  } catch (error) {
    console.error("Error fetching data:", error);
    throw error; // æŠ›å‡ºé”™è¯¯ï¼Œè®©è°ƒç”¨æ–¹å¯ä»¥æ•获
@@ -36,7 +38,7 @@
export async function getSimDataById(id) {
  try {
    const res = await instance.get(`/simu/selectPage?id=${id}`);
    return res.data; // è¿”回实际数据(通常 res.data æ‰æ˜¯æŽ¥å£è¿”回的内容)
    return res.data;
  } catch (error) {
    console.error("Error fetching data:", error);
    throw error; // æŠ›å‡ºé”™è¯¯ï¼Œè®©è°ƒç”¨æ–¹å¯ä»¥æ•获
@@ -132,7 +134,7 @@
// èŽ·å–æ°´ä½æ°´æ·±
export async function getFlowRate(data) {
  // console.log(data,'发送的数据!');
  try {
    const res = await instance.get("/simu/position", {
      params: data
src/components/monifangzhen/echartInfo.vue
@@ -350,6 +350,7 @@
            rainfallData.value = rainfallData.value.map((item) => ({
              ...item,
              intensity: item.intensity * 60,
              total: item.total * 60,
            }));
          }
src/components/monifangzhen/schemeCard.vue
@@ -13,7 +13,10 @@
        <p>创建时间 : {{ formatTime(item.createTime) }}</p>
        <p>
          æ–¹æ¡ˆçŠ¶æ€ :
          <span style="color: aquamarine">{{ item.result || "创建仿真" }}</span>
          <span style="color: aquamarine">
            {{ item.result === -1 ? "出错" : item.result || "创建仿真" }}
          </span>
          <!-- <span style="color: aquamarine">{{ item.result || "创建仿真" }}</span> -->
          <!-- <span style="color: aquamarine">{{
            statusText[item.status] || "未知"
          }}</span> -->
@@ -50,12 +53,20 @@
import { initeWaterPrimitiveView } from "@/utils/water";
import Message from "@/components/tools/Message.vue";
import { useSimStore } from "@/store/simulation.js";
import { SimAPIStore } from "@/store/simAPI";
import schemeInfo from "@/components/monifangzhen/schemeInfo.vue";
import { ElMessage, ElMessageBox } from "element-plus";
const emit = defineEmits(["start", "end", "reset", "closeBtn"]);
import { getSimStart, getSimDataById } from "@/api/trApi";
import {
  getRegionData,
  getSimData,
  deleteSimData,
  getSimStart,
  getSimDataById,
} from "@/api/trApi.js";
const simStore = useSimStore();
const simAPIStore = SimAPIStore();
// é€‰ä¸­çš„æ–¹æ¡ˆ ID
const selectedId = ref(null);
// å½“前选中的方案信息
@@ -72,16 +83,22 @@
  10: "完成",
  20: "出错",
};
function formatTime(time) {
  return dayjs(time).format("YYYY-MM-DD HH:mm:ss");
}
const messageShow = ref(false);
const schemeInfoShow = ref(false);
const mesData = ref(null);
function setSchemClick(item) {
  mesData.value = item;
  messageShow.value = true;
}
function close() {
  messageShow.value = false;
}
@@ -113,8 +130,11 @@
    simStore.setSelectedScheme(item);
    console.log("有服务名称");
  }
  const flyHeight = ref(100000);
  const shouldShowFill = false;
  // æ±‚解器求解完成之后才可以显示时间轴
  if (item.status == 10) {
    // åªæœ‰è¡Œæ”¿åŒºåˆ’执行
@@ -135,14 +155,17 @@
    emit("start");
  }
}
function endPlay() {
  emit("end");
}
function handleBack(value) {
  if (value === false) {
    schemeInfoShow.value = false;
  }
}
const handleHideSchemeInfo = () => {
  schemeInfoShow.value = false;
  emit("closeBtn", true);
@@ -151,26 +174,6 @@
// æ³¨å†Œäº‹ä»¶ç›‘听器
EventBus.on("hide-schemeInfo", handleHideSchemeInfo);
/////////////////////// è°ƒç”¨æŽ¥å£ï¼ˆä½¿ç”¨æ—¶æ‰“开) ///////////////////////
import { getRegionData, getSimData, deleteSimData } from "@/api/trApi.js";
onMounted(() => {
  getScheme(); // é¡µé¢åŠ è½½æ—¶ç«‹å³èŽ·å–æ•°æ®
  intervalId = setInterval(getScheme, 60 * 1000); // æ¯éš”一分钟执行一次
});
onUnmounted(() => {
  if (intervalId !== null) {
    clearInterval(intervalId); // æ¸…除定时器
    intervalId = null; // é‡ç½® intervalId
  }
});
const props = defineProps({
  deleteSim: Boolean, // æŽ¥æ”¶çˆ¶ç»„件传递的函数
  showAddIns: Boolean,
});
const schemeList = ref([]);
let intervalId = null; // ç”¨äºŽå­˜å‚¨ setInterval çš„返回值
// èŽ·å–æ–¹æ¡ˆåˆ—è¡¨
@@ -178,10 +181,49 @@
  try {
    const res = await getSimData();
    schemeList.value = res.data;
    const shouldStop = schemeList.value.every(
      (item) =>
        item.result == "创建仿真" ||
        item.result == "完成" ||
        item.result == "-1"
    );
    simAPIStore.shouldPoll = !shouldStop; // ä¿®æ”¹ Pinia çŠ¶æ€
    // 3. å¦‚果需要停止
    if (shouldStop) {
      if (intervalId) {
        clearInterval(intervalId);
        intervalId = null;
        console.log("停止轮询");
      }
      return;
    }
  } catch (error) {
    console.error("Error fetching data:", error);
  }
}
// ç›‘听 shouldPoll çŠ¶æ€å˜åŒ–
watch(
  () => simAPIStore.shouldPoll,
  (isStarted) => {
    console.log(isStarted, "定时器");
    if (isStarted) {
      getScheme(); // é¦–次立即获取一次
      intervalId = setInterval(getScheme, 60 * 1000); // æ¯éš”一分钟执行
    }
    // else if (intervalId !== null) {
    //   clearInterval(intervalId);
    //   intervalId = null;
    // }
  },
  { immediate: true }
);
const props = defineProps({
  deleteSim: Boolean, // æŽ¥æ”¶çˆ¶ç»„件传递的函数
  showAddIns: Boolean,
});
// æ–°å»ºæ–¹æ¡ˆå®Œæˆä¹‹åŽæ–¹æ¡ˆåˆ—表需实时刷新
watch(
@@ -231,9 +273,18 @@
    })
    .catch(() => {});
};
/////////////////////// è°ƒç”¨æŽ¥å£ç»“束 ///////////////////////
onMounted(() => {
  getScheme(); // é¡µé¢åŠ è½½æ—¶ç«‹å³èŽ·å–æ•°æ®
});
onUnmounted(() => {
  EventBus.off("hide-schemeInfo", handleHideSchemeInfo);
  if (intervalId !== null) {
    clearInterval(intervalId); // æ¸…除定时器
    intervalId = null; // é‡ç½® intervalId
  }
});
</script>
src/components/tools/LayerTree.vue
@@ -101,7 +101,9 @@
    // åˆå§‹åŒ–地形数据(使用await等待Promise解析)
    TerrainLayer = await earthCtrl.factory.createTerrainLayer({
      sourceType: "ctb",
      url: "http://106.120.22.26:9103/gisserver/ctsserver/sungugoudem",
      url: "http://106.120.22.26:9103/gisserver/ctsserver/sunhugoudem",
      // url: "https://tiles1.geovisearth.com/base/v1/terrain?token=486dac3bec56d7d7c2a581c150be2bd937462f1e8f3bc9c78b5658b396122405",
      requestVertexNormals: true,
    });
    treeMap.set("地形数据", TerrainLayer);
@@ -187,27 +189,27 @@
  if (label === "综合监测设备信息") {
    simStore.DeviceShowSwitch = checked;
    if (checked) {
    if (!treeMap.get("综合监测设备信息")) {
      if (!treeMap.get("综合监测设备信息")) {
      } else {
        toggleLayerVisible("综合监测设备信息", true);
      }
    } else {
      toggleLayerVisible("综合监测设备信息", true);
      toggleLayerVisible("综合监测设备信息", false);
    }
  } else {
    toggleLayerVisible("综合监测设备信息", false);
    return;
  }
  return;
}
if (label === "孙胡沟隐患点") {
  if (label === "孙胡沟隐患点") {
    simStore.DangerShowSwitch = checked;
    if (checked) {
    if (!treeMap.get("孙胡沟隐患点")) {
      if (!treeMap.get("孙胡沟隐患点")) {
      } else {
        toggleLayerVisible("孙胡沟隐患点", true);
      }
    } else {
      toggleLayerVisible("孙胡沟隐患点", true);
      toggleLayerVisible("孙胡沟隐患点", false);
    }
  } else {
    toggleLayerVisible("孙胡沟隐患点", false);
    return;
  }
  return;
}
  // å…¶ä»–图层的处理逻辑
  const list = treeMap.get(label);
src/components/tools/Message.vue
@@ -178,7 +178,7 @@
          };
          addField("total", "降雨总量(mm)");
          addField("duration", "小时");
          addField("duration", "降雨时长(h)");
          addField("intensity", "降雨强度(mm/小时)");
          addField("prediction", "降雨场次");
          addField("model", "降雨模式");
src/components/tools/TopographyDia.vue
@@ -46,7 +46,7 @@
}
/deep/ .el-input__wrapper {
  background-color: #fff !important;
  // background-color: #8b2f2f !important;
  border: none !important;
}
</style>
src/store/simAPI.js
@@ -5,6 +5,10 @@
import dayjs from 'dayjs'
export const SimAPIStore = defineStore('SimAPI', () => {
    // å®šæ—¶å™¨
    const shouldPoll = ref(false)
    const selectTab = ref("行政区划仿真")
    const isLoading = ref(false)
@@ -31,14 +35,23 @@
        }
        if (forms.type === 1 || forms.type === 3) {
            if (!forms.geom || !forms.rainfall || !forms.intensity || !forms.duration) {
            if (!forms.geom) {
                ElMessage.warning('请选择模拟区域')
                return false
            }
            if (!forms.rainfall || !forms.intensity || !forms.duration) {
                ElMessage.warning('请确保表单均已填写')
                return false
            }
        }
        if (forms.type === 2) {
            if (!forms.geom || !forms.gauges) {
                ElMessage.warning('请确保表单均已填写')
            if (!forms.geom) {
                ElMessage.warning('请选择模拟区域')
                return false
            }
            if (forms.gauges.length === 0) {
                ElMessage.warning('请选择雨量计设备')
                return false
            }
        }
@@ -80,7 +93,7 @@
                    intensityUnit: forms.intensityUnit || 'mm/15min'
                })
            }
            console.log(params, '保存方案参数')
            // console.log(params, '保存方案参数')
            const res = await createSimData(params)
            ElMessage.success('方案保存成功')
            return res
@@ -124,6 +137,7 @@
    return {
        selectTab,
        isLoading,
        shouldPoll,
        handleClickTab,
        addSimCheme,
        saveScheme,
src/store/simulation.js
@@ -1,7 +1,6 @@
// stores/ui.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { createSimData } from '@/api/trApi'
export const useSimStore = defineStore('simulation', () => {
    // é𐿂£ç‚¹åˆ—表
@@ -30,7 +29,9 @@
    const schemCard = ref([])
    const backToHome = ref(false)
    const selectedScheme = ref(null)
    // é™é›¨æ•°æ®åˆ—表
    const rainFalls = ref()
    // é™é›¨å•位
    const intensityUnit = ref()
    const setSelectedScheme = (scheme) => {
        selectedScheme.value = scheme
src/views/left/CitySim.vue
@@ -10,7 +10,11 @@
    <div class="left-top" v-if="simStore.selectTab == '重点区域仿真'">
      é‡ç‚¹åŒºåŸŸä»¿çœŸï¼ˆ10m精度)
    </div>
    <div class="forms">
    <div class="left-top" v-if="simStore.selectTab == '重点沟仿真'">
      åŽ†å²æ¨¡æ‹Ÿ
    </div>
    <div class="forms" :class="{ 'no-background': !showBackground }">
      <el-form
        :rules="rules"
        :model="forms"
@@ -106,7 +110,7 @@
            v-if="forms.fileList.length !== 0"
            v-model="forms.hours"
            type="datetime"
            placeholder="Select date and time"
            placeholder="请选择开始时间"
          />
          <el-date-picker
            v-if="forms.fileList.length == 0"
@@ -169,6 +173,14 @@
const options = reactive([]);
// åŽ†å²æ¨¡æ‹Ÿé€‰ä¸­åŒºåŸŸ
const props = defineProps({
  selectedArea: {
    type: Object,
    required: true,
  },
});
const intensityOptions = ref([
  { value: "mm/h", label: "mm/h" },
  { value: "mm/5min", label: "mm/5min" },
@@ -193,6 +205,8 @@
  fetchRegionData(1);
});
const showBackground = ref(true); // é»˜è®¤æ˜¾ç¤ºèƒŒæ™¯å›¾
// ç›‘听 selectTab çš„变化
watch(selectTab, (newVal) => {
  let type;
@@ -203,10 +217,21 @@
    case "重点区域仿真":
      type = 2;
      break;
    case "重点沟仿真":
      type = 3;
      break;
    default:
      type = 1; // é»˜è®¤å€¼
  }
  // æ ¹æ® type è®¾ç½®æ˜¯å¦æ˜¾ç¤ºèƒŒæ™¯å›¾ï¼ˆå› ä¸ºåŽ†å²æ¨¡æ‹Ÿä¸­è¡¨å•å¸¦äº†èƒŒæ™¯å›¾ï¼‰
  if (type == 3) {
    showBackground.value = false;
  } else {
    showBackground.value = true;
  }
  fetchRegionData(type);
  // Tab切换的时候清空表单
  resetForm();
});
// æ³¨å…¥çˆ¶ç»„件提供的方法
@@ -245,6 +270,9 @@
const addSimCheme = async () => {
  try {
    if (selectTab.value == "重点沟仿真") {
      forms.geom = props.selectedArea;
    }
    await simStore.addSimCheme(forms);
    resetForm(); // åªæœ‰åœ¨ä¿å­˜æˆåŠŸåŽæ‰é‡ç½®è¡¨å•
    EventBus.emit("close-selectArea");
@@ -471,6 +499,9 @@
async function startPlay() {
  try {
    // ä¿å­˜æ–¹æ¡ˆ
    if (selectTab.value == "重点沟仿真") {
      forms.geom = props.selectedArea;
    }
    const res = await simStore.addSimCheme(forms);
    const schemeId = res.data?.data?.id;
@@ -481,10 +512,11 @@
    // è°ƒç”¨æ±‚解器
    const simStartRes = await getSimStart(schemeId);
    console.log(simStartRes, "getSimStart è¿”回结果");
    // å…³é—­é€‰æ‹©åŒºåŸŸçª—口、初始化视图并开始模拟
    EventBus.emit("close-selectArea");
    simStore.shouldPoll = true;
    // æš‚时不在此处开始模拟,模拟都在方案列表中进行模拟
    // initeWaterPrimitiveView();
    // startSimulate();
@@ -508,6 +540,12 @@
  height: 100%;
  padding: 10px 10px 0px 0px;
  box-sizing: border-box;
  transition: background 0.3s ease; // å¯é€‰è¿‡æ¸¡æ•ˆæžœ
}
.forms.no-background {
  margin-top: 0px;
  background-image: none;
}
/deep/ .el-input-group__append,
.el-input-group__prepend {
src/views/left/KGSim.vue
@@ -36,7 +36,8 @@
        <el-radio label="预测模拟">预测模拟</el-radio>
      </el-radio-group>
      <div v-if="selectedSimulation === '历史模拟'">
        <HistorySimulation :selectedArea="selectedArea" />
        <!-- <HistorySimulation :selectedArea="selectedArea" /> -->
        <CitySim :selectedArea="selectedArea" />
      </div>
      <div v-if="selectedSimulation === '实时模拟'">
        <RealTimeSimulation :selectedArea="selectedArea" />
@@ -51,6 +52,7 @@
<script setup>
import { ref, computed, onMounted, reactive } from "vue";
import HistorySimulation from "./KGSimOption/HistorySimulation.vue";
import CitySim from './CitySim.vue'
import PredictiveSimulation from "./KGSimOption/PredictiveSimulation.vue";
import RealTimeSimulation from "./KGSimOption/RealTimeSimulation.vue";
import { getRegionData } from "@/api/trApi";
src/views/left/KGSimOption/HistorySimulation.vue
@@ -202,7 +202,6 @@
    });
  } catch (error) {
    ElMessage.error("启动模拟失败,请稍后再试");
    console.log(error, "errorerrorerror");
  }
}
</script>
src/views/left/KGSimOption/PredictiveSimulation.vue
@@ -88,7 +88,7 @@
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="选择时间:">
      <el-form-item label="选择时间:" v-show="forms.prediction != '降雨场次'">
        <el-date-picker
          v-model="forms.hours"
          type="datetimerange"
@@ -98,6 +98,13 @@
          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="预计时长:">
@@ -113,7 +120,7 @@
    <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>
      <el-button type="success" @click="startPlay">保存并开始模拟</el-button>
    </div>
  </div>
</template>
@@ -214,7 +221,7 @@
    .slice(1)
    .reduce((acc, curr, i) => acc + parseInt(curr, 10) / (i === 0 ? 1 : 60), 0)
    .toFixed(1);
  console.log(parseFloat(decimalHours)); // è¾“出: 2.6
  // console.log(parseFloat(decimalHours)); // è¾“出: 2.6
  forms.duration = decimalHours;
  forms.intensity = val.rainIntensityHour;
  forms.rainfall = val.rainfallTotalValue;
@@ -261,7 +268,7 @@
// å¼€å§‹æ¨¡æ‹Ÿ
async function startPlay() {
  try {
    formData.geom = props.selectedArea;
    forms.geom = props.selectedArea;
    // ä¿å­˜æ–¹æ¡ˆ
    const res = await simStore.addSimCheme(forms);
    const schemeId = res.data?.data?.id;
@@ -277,6 +284,8 @@
    // å…³é—­é€‰æ‹©åŒºåŸŸçª—口、初始化视图并开始模拟
    EventBus.emit("close-selectArea");
    simStore.shouldPoll = true;
    // æš‚时不在此处开始模拟,模拟都在方案列表中进行模拟
    // initeWaterPrimitiveView();
    // startSimulate();
@@ -287,6 +296,7 @@
    });
  } catch (error) {
    ElMessage.error("启动模拟失败,请稍后再试");
    console.log(error);
  }
}
src/views/left/KGSimOption/RealTimeSimulation copy.vue
ÎļþÒÑɾ³ý