wangjuncheng
2025-05-12 0263bbda73cce47ae1f9f302ea44bbe6c51f1603
change
已修改5个文件
451 ■■■■ 文件已修改
src/components/monifangzhen/schemeInfo.vue 443 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/Legend_yhgl.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/Legend_zhjc.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/tools/Rain.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/GisView.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/schemeInfo.vue
@@ -1,259 +1,235 @@
<template>
  <div class="listCard">
    <div class="top">
      <span>方案详情</span>
      <!-- <el-button class="clickable-text" @click="handleBack">结束模拟</el-button> -->
    <div class="top"><span>方案详情</span>
      <div @click="togglePick" :class="['pick-button', { active: isPickingActive }]">
        {{ isPickingActive ? '进行计算' : '开始拾取' }}
      </div>
    </div>
    <div class="details">
      <div v-if="formattedData.length > 0">
        <div class="input-group">
          <div v-for="(item, index) in formattedData" :key="index" class="input-item">
            <label>{{ item.name }}</label>
            <span>{{ item.value }}</span>
          </div>
      <div v-if="formattedData.length" class="input-group">
        <div v-for="(item, index) in formattedData" :key="index" class="input-item">
          <label>{{ item.name }}</label>
          <span>{{ item.value }}</span>
        </div>
      </div>
      <div v-else>
        <p style="text-align: center">暂无方案信息</p>
      </div>
    </div>
    <div>
    </div>
  </div>
  <Message
    @close="close"
    class="mess"
    v-show="messageShow"
    :mesData="mesData"
  />
  <Message @close="close" class="mess" v-show="messageShow" :mesData="mesData" />
</template>
<script setup>
import { defineProps, defineEmits, inject ,ref,watch} from "vue";
import { defineProps, defineEmits, inject, ref, watch } from "vue";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
// 定义 emit 方法
// 公共依赖
const props = defineProps({ selectedScheme: { type: Object, default: null } });
const emit = defineEmits(["back"]);
const { startSimulate, endSimulate } = inject("simulateActions");
const { endSimulate } = inject("simulateActions");
// 返回按钮点击事件
function handleBack() {
  ElMessage({
    message: "模拟进程正在关闭中...",
    type: "success",
  });
  emit("back", false); // 向父组件传递 false 值
  endSimulate();
// 状态管理
const formattedData = ref([]);
const pickedPoints = ref([]);
const handler = ref(null);
const isPickingActive = ref(false);
// 映射表
const areaTypeMap = {
  0: "自定义区域仿真",
  1: "行政区划仿真",
  2: "重点区域仿真",
  3: "重点沟仿真"
};
const statusMap = {
  0: "创建仿真",
  1: "预处理",
  2: "分析中",
  10: "完成",
  20: "出错"
};
const typeMap = {
  1: "预测模拟",
  2: "实时模拟",
  3: "历史模拟"
};
// 跳过字段列表
const skipKeys = ["geom", "id", "serviceName", "updateTime", "updateUser", "createUser", "bak"];
// 处理 data 字段解析
function parseDataField(dataStr) {
  if (typeof dataStr !== "string") return [];
  try {
    const parsed = JSON.parse(dataStr);
    const fields = {
      total: "降雨总量(mm):",
      duration: "降雨时长(分钟):",
      intensity: "降雨强度(mm/小时):",
      prediction: "降雨场次:",
      model: "降雨模式:",
      history: "历史降雨:",
      gauges: "雨量计列表:"
    };
    return Object.entries(parsed)
      .filter(([k]) => fields[k])
      .map(([k, v]) => ({
        name: fields[k],
        value: Array.isArray(v) ? v.join(", ") : v || "无"
      }));
  } catch (e) {
    return [{ name: "数据:", value: dataStr || "无" }];
  }
}
// 接收父组件传递的 props
const props = defineProps({
  selectedScheme: {
    type: Object,
    default: null,
  },
});
// 格式化后的数据
const formattedData = ref([]);
// 监听 selectedScheme 的变化
watch(
  () => props.selectedScheme,
  (newScheme) => {
    // console.log(newScheme, "弹窗的数据");
    // 检查数据有效性
    if (!newScheme || typeof newScheme !== "object") {
      console.warn("Invalid selectedScheme received:", newScheme);
      formattedData.value = [];
      return;
    }
    // 将所有字段转换为列表形式
    const data = [];
    // 提前解析 areaType,确保其存在性
    const areaType = newScheme.areaType !== undefined ? newScheme.areaType : null;
    for (const [key, value] of Object.entries(newScheme)) {
      // 跳过不需要的字段
      if (["geom", "id", "serviceName", "updateTime", "updateUser", "createUser", "bak"].includes(key)) continue;
      // 特殊处理 createTime 字段
      if (key === "createTime" && typeof value === "number") {
        data.push({
          name: "创建时间:",
          value: formatDate(value),
        });
        continue;
      }
      // 处理 areaType 字段
      if (key === "areaType") {
        const areaTypeMap = {
          0: "自定义区域仿真",
          1: "行政区划仿真",
          2: "重点区域仿真",
          3: "重点沟仿真",
        };
        data.push({
          name: "区域类别:",
          value: areaTypeMap[value] || "未知",
        });
        continue;
      }
      // 处理 status 字段
      if (key === "status") {
        const statusMap = {
          0: "创建仿真",
          1: "预处理",
          2: "分析中",
          10: "完成",
          20: "出错",
        };
        data.push({
          name: "仿真状态:",
          value: statusMap[value] || "未知",
        });
        continue;
      }
      // 处理 type 字段(仅在 areaType 不为 1 或 2 时显示)
      if (key === "type") {
        if (![1, 2].includes(areaType)) {
          const typeMap = {
            1: "预测模拟",
            2: "实时模拟",
            3: "历史模拟",
          };
          data.push({
            name: "模拟类别:",
            value: typeMap[value] || "未知",
          });
        }
        continue;
      }
      // 处理 areaName 字段
      if (key === "areaName") {
        data.push({
          name: "区域名称:",
          value: value || "无",
        });
        continue;
      }
      // 处理 result 字段
      if (key === "result") {
        data.push({
          name: "仿真结果:",
          value: value || "无",
        });
        continue;
      }
      // 处理 name 字段
      if (key === "name") {
        data.push({
          name: "仿真方案:",
          value: value || "无",
        });
        continue;
      }
      // 处理 data 字段
      if (key === "data" && typeof value === "string") {
        try {
          const parsedData = JSON.parse(value);
          // 处理 data.total 字段
          if (parsedData.total !== undefined) {
            data.push({
              name: "降雨总量(mm):",
              value: parsedData.total || "无",
            });
          }
          // 处理 data.duration 字段
          if (parsedData.duration !== undefined) {
            data.push({
              name: "降雨时长(分钟):",
              value: parsedData.duration || "无",
            });
          }
          // 处理 data.intensity 字段
          if (parsedData.intensity !== undefined) {
            data.push({
              name: "降雨强度(mm/小时):",
              value: parsedData.intensity || "无",
            });
          }
          // 处理 data.prediction 字段
          if (parsedData.prediction !== undefined) {
            data.push({
              name: "降雨场次:",
              value: parsedData.prediction || "无",
            });
          }
          // 处理 data.model 字段
          if (parsedData.model !== undefined) {
            data.push({
              name: "降雨模式:",
              value: parsedData.model || "无",
            });
          }
          // 处理 data.history 字段
          if (parsedData.history !== undefined) {
            data.push({
              name: "历史降雨:",
              value: parsedData.history || "无",
            });
          }
          // 处理 data.gauges 字段
          if (parsedData.gauges !== undefined) {
            data.push({
              name: "雨量计列表:",
              value: Array.isArray(parsedData.gauges) ? parsedData.gauges.join(", ") : "无",
            });
          }
        } catch (e) {
          data.push({
            name: "数据:",
            value: value || "无",
          });
        }
        continue;
      }
      // 其他字段直接展示
      data.push({
        name: `${key}:`,
        value: value || "无",
      });
    }
    // 更新 formattedData
    formattedData.value = data;
  },
  { immediate: true } // 立即执行一次
);
// 格式化时间戳为日期
// 格式化时间戳
function formatDate(timestamp) {
  return dayjs(timestamp).format("YYYY-MM-DD HH:mm:ss");
}
// 定义任务状态的文本映射
const statusText = {
  0: "未开始",
  1: "进行中",
  2: "已完成",
};
// 格式化 selectedScheme 数据
watch(
  () => props.selectedScheme,
  (newScheme) => {
    if (!newScheme || typeof newScheme !== "object") {
      formattedData.value = [];
      return;
    }
    const entries = Object.entries(newScheme);
    const areaType = newScheme.areaType;
    const result = entries.reduce((acc, [key, value]) => {
      if (skipKeys.includes(key)) return acc;
      switch (key) {
        case "createTime":
          acc.push({ name: "创建时间:", value: formatDate(value) });
          break;
        case "areaType":
          acc.push({ name: "区域类别:", value: areaTypeMap[value] || "未知" });
          break;
        case "status":
          acc.push({ name: "仿真状态:", value: statusMap[value] || "未知" });
          break;
        case "type":
          if (![1, 2].includes(areaType)) {
            acc.push({ name: "模拟类别:", value: typeMap[value] || "未知" });
          }
          break;
        case "areaName":
          acc.push({ name: "区域名称:", value: value || "无" });
          break;
        case "result":
          acc.push({ name: "仿真结果:", value: value || "无" });
          break;
        case "name":
          acc.push({ name: "仿真方案:", value: value || "无" });
          break;
        case "data":
          acc.push(...parseDataField(value));
          break;
        default:
          acc.push({ name: `${key}:`, value: value || "无" });
      }
      return acc;
    }, []);
    formattedData.value = result;
  },
  { immediate: true }
);
// 拾取相关逻辑
const viewer = window.viewer;
function getPickPosition(windowPosition) {
  if (!viewer) return null;
  viewer.scene.globe.depthTestAgainstTerrain = true;
  const cartesian = viewer.scene.pickPosition(windowPosition);
  if (!cartesian) return null;
  const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  // 在原有高度上增加300米
  cartographic.height += 80.0;
  return {
    cartesian: Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height),
    longitude: Cesium.Math.toDegrees(cartographic.longitude),
    latitude: Cesium.Math.toDegrees(cartographic.latitude),
    height: cartographic.height
  };
}
function addPointToViewer(point, index) {
  const entity = viewer.entities.add({
    position: point.cartesian,
    billboard: {
      // image: '../path/to/your/icon.png', // 替换为你的图标路径
      width: 32, // 图标宽度
      height: 32, // 图标高度
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM
    },
    label: {
      text: `Point ${index + 1}\n经度: ${point.longitude.toFixed(6)}\n纬度: ${point.latitude.toFixed(6)}`,
      font: '14pt monospace',
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      outlineWidth: 2,
      verticalOrigin: Cesium.VerticalOrigin.TOP,
      pixelOffset: new Cesium.Cartesian2(0, -40), // 调整标签相对于图标的偏移量
      fillColor: Cesium.Color.WHITE,
      outlineColor: Cesium.Color.BLACK
    }
  });
  // 可选:存储实体引用以便后续操作
  pickedPoints.value.push(entity);
}
function initPickHandler() {
  if (!viewer?.scene?.canvas) return;
  handler.value = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  handler.value.setInputAction((movement) => {
    const position = getPickPosition(movement.position);
    if (position) {
      const index = pickedPoints.value.length;
      pickedPoints.value.push(position);
      addPointToViewer(position, index);
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
function togglePick() {
  isPickingActive.value ? stopPicking() : startPicking();
}
function startPicking() {
  pickedPoints.value = [];
  viewer.entities.removeAll();
  !handler.value && initPickHandler();
  isPickingActive.value = true;
}
function stopPicking() {
  if (handler.value) {
    handler.value.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler.value.destroy();
    handler.value = null;
  }
  isPickingActive.value = false;
}
</script>
<style lang="less" scoped>
@@ -315,13 +291,16 @@
    }
  }
}
.mess {
  position: absolute;
  top: 10%;
  left: 100%;
  z-index: 5000;
}
.top {
  display: flex;
  width: 100%;
  height: 41px;
  color: white;
src/components/tools/Legend_yhgl.vue
@@ -32,7 +32,7 @@
<style lang="less" scoped>
.legend-container {
  padding: 0.5rem; // 减少内边距
  padding: 1rem; // 减少内边距
  // background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 8px;
src/components/tools/Legend_zhjc.vue
@@ -37,7 +37,7 @@
<style lang="less" scoped>
.legend-container {
  padding: 0.5rem; // 减少内边距
  padding: 1rem; // 减少内边距
  // background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 8px;
src/components/tools/Rain.vue
@@ -3,7 +3,7 @@
    <el-form-item label="大小">
      <el-slider :step="0.1" v-model="form.rainSize" :min="0" :max="1"></el-slider>
    </el-form-item>
    <el-form-item label="密度:">
    <el-form-item label="密度">
      <el-slider :step="10" :min="10" :max="100" v-model="form.rainDensity">
      </el-slider>
    </el-form-item>
src/views/GisView.vue
@@ -27,7 +27,7 @@
  // 1. 设置初始时间
  const date = new Date(2025, 3, 11, 12, 0, 0, 0);
  const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date);
  const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date);
  // earthCtrl.viewer.clock.currentTime = julianDate;
  // 2. 配置时钟选项,禁止自动推进时间