Merge branch 'master' of http://103.135.160.14:9034/r/NslWeb
| | |
| | | <span>监测设备</span> |
| | | </div> |
| | | <div class="left-content device-content"> |
| | | <div style="margin-left: 5px; margin-bottom: 5px"> |
| | | <span style="color: white">北京市:</span> |
| | | <el-select |
| | | @change="handleChange1" |
| | | v-model="selectValue1" |
| | | placeholder="Select" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="item in BJoptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-left: 5px"> |
| | | <span style="color: white">重点沟:</span> |
| | | <el-select |
| | | @change="handleChange" |
| | | v-model="selectValue" |
| | | placeholder="Select" |
| | | size="large" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | <!-- 加载遮罩层和内容容器 --> |
| | | <div class="tree-container"> |
| | | <div v-if="isLoading" class="loading-overlay"> |
| | | <div class="loading-content"> |
| | | <el-icon class="loading-icon"><Loading /></el-icon> |
| | | <span class="loading-text">数据加载中...</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-tree |
| | | v-show="!isLoading" |
| | | :data="deviceTree" |
| | | node-key="deviceId" |
| | | :props="treeProps" |
| | |
| | | > |
| | | <template #default="{ node, data }"> |
| | | <span v-if="!data.children" class="device-tree-item"> |
| | | <!-- <div class="device-item-icon"></div> --> |
| | | <span class="device-item-text">{{ node.label }}</span> |
| | | </span> |
| | | <span v-else class="device-tree-category"> |
| | |
| | | </span> |
| | | </template> |
| | | </el-tree> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | import { getDeviceInfo } from "@/api/hpApi"; |
| | | import { initeWaterPrimitiveView } from "@/utils/water"; //相机flyTo函数,后续options列表中有对应经纬度后弃用 |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { Loading } from "@element-plus/icons-vue"; |
| | | |
| | | const simStore = useSimStore(); |
| | | |
| | | const isLoading = ref(true); // 初始设置为加载状态 |
| | | |
| | | onMounted(async () => { |
| | | // 加载所有的隐患点信息 |
| | | try { |
| | | await getData(); |
| | | loadDeviceList("孙胡沟"); |
| | | await loadDeviceList(selectValue.value); |
| | | initeWaterPrimitiveView(); |
| | | } finally { |
| | | isLoading.value = false; |
| | | } |
| | | }); |
| | | |
| | | onBeforeRouteUpdate((to, from, next) => { |
| | |
| | | } |
| | | } |
| | | ); |
| | | |
| | | const deviceListAll = ref([]); |
| | | const deviceEntities = ref([]); |
| | | const handleCleanup = () => { |
| | |
| | | // 根据区域名称加载设备列表 |
| | | const loadDeviceList = async (areaName) => { |
| | | try { |
| | | isLoading.value = true; |
| | | handleCleanup(); |
| | | // const res = await getDeviceInfo(); |
| | | // const allDevices = res.data.pageData; |
| | |
| | | initializeDevicePoints(); |
| | | } catch (error) { |
| | | console.error("加载设备信息失败", error); |
| | | } finally { |
| | | isLoading.value = false; |
| | | } |
| | | }; |
| | | |
| | |
| | | // console.log(deviceListAll.value); |
| | | }; |
| | | |
| | | const selectValue1 = ref("北京市"); |
| | | |
| | | const BJoptions = ref([]); |
| | | |
| | | const selectValue = ref("孙胡沟"); |
| | | |
| | | const options = ref([ |
| | | { |
| | | value: "孙胡沟", |
| | | label: "孙胡沟", |
| | | }, |
| | | { |
| | | value: "鱼水洞后沟", |
| | | label: "鱼水洞后沟", |
| | | }, |
| | | { |
| | | value: "于家西沟", |
| | | label: "于家西沟", |
| | | }, |
| | | { |
| | | value: "北河沟", |
| | | label: "北河沟", |
| | | }, |
| | | { |
| | | value: "龙泉峪村", |
| | | label: "龙泉峪村", |
| | | }, |
| | | { value: "孙胡沟", label: "孙胡沟" }, |
| | | { value: "鱼水洞后沟", label: "鱼水洞后沟" }, |
| | | { value: "于家西沟", label: "于家西沟" }, |
| | | { value: "北河沟", label: "北河沟" }, |
| | | { value: "龙泉峪村", label: "龙泉峪村" }, |
| | | ]); |
| | | |
| | | const treeProps = { |
| | |
| | | children: typeMap[typeName], |
| | | })); |
| | | }); |
| | | |
| | | function handleTreeNodeClick(data) { |
| | | // 只有设备节点才处理点击事件 |
| | | if (!data.children) { |
| | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .device { |
| | | position: absolute; |
| | |
| | | z-index: 99; |
| | | } |
| | | |
| | | .left-top { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | color: white; |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.1); |
| | | } |
| | | |
| | | .device-content { |
| | | padding: 10px; |
| | | box-sizing: border-box; |
| | | overflow-y: auto; |
| | | height: calc(100% - 70px); |
| | | position: relative; |
| | | } |
| | | |
| | | .tree-container { |
| | | position: relative; |
| | | height: calc(100% - 80px); |
| | | margin-top: 10px; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .loading-overlay { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | // background-color: rgba(0, 0, 0, 0.7); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 100; |
| | | // border-radius: 4px; |
| | | } |
| | | |
| | | .loading-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | color: #fff; |
| | | } |
| | | |
| | | .loading-icon { |
| | | font-size: 24px; |
| | | margin-bottom: 8px; |
| | | animation: rotating 2s linear infinite; |
| | | } |
| | | |
| | | .loading-text { |
| | | font-size: 14px; |
| | | } |
| | | |
| | | @keyframes rotating { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .device-tree { |
| | |
| | | color: #fff; |
| | | } |
| | | |
| | | .device-item-icon { |
| | | background: url("@/assets/img/menu/locationicon.png") no-repeat; |
| | | background-position: 5px 5px; |
| | | width: 30px; |
| | | height: 30px; |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | .device-item-text { |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | // 保持原有的选择器样式 |
| | | :deep(.el-select__placeholder) { |
| | | color: white; |
| | | } |
| | |
| | | :deep(.el-select-dropdown__item.hover), |
| | | :deep(.el-select-dropdown__item:hover) { |
| | | color: white !important; |
| | | background-color: rgb(38, 124, 124, 0.5); |
| | | background-color: rgba(38, 124, 124, 0.5); |
| | | } |
| | | |
| | | :deep(.el-tree-node__content) { |
| | |
| | | </div> |
| | | |
| | | <div class="left-content district-content"> |
| | | <div style="margin-left: 5px; margin-bottom: 5px"> |
| | | <span style="color: white">北京市:</span> |
| | | <el-select |
| | | @change="handleChange1" |
| | | v-model="selectValue1" |
| | | placeholder="Select" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="item in BJoptions" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | <div style="margin-left: 5px"> |
| | | <span style="color: white">重点沟:</span> |
| | | <el-select |
| | | @change="handleChange" |
| | | v-model="selectValue" |
| | | placeholder="Select" |
| | | size="large" |
| | | size="mini" |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | |
| | | </div> |
| | | |
| | | <!-- 滚动区域 --> |
| | | <div style="overflow-y: auto; height: 95%"> |
| | | <div style="overflow-y: auto; height: 91%; position: relative"> |
| | | <!-- 加载遮罩层 --> |
| | | <div v-if="loading" class="loading-overlay"> |
| | | <div class="spinner"></div> |
| | | <div class="loading-content"> |
| | | <el-icon class="loading-icon"><Loading /></el-icon> |
| | | <span class="loading-text">数据加载中...</span> |
| | | </div> |
| | | </div> |
| | | <div |
| | | v-else |
| | |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { initeWaterPrimitiveView } from "@/utils/water"; //相机flyTo函数,后续options列表中有对应经纬度后弃用 |
| | | import { useRoute, onBeforeRouteUpdate } from "vue-router"; |
| | | import { Loading } from "@element-plus/icons-vue"; |
| | | |
| | | const simStore = useSimStore(); |
| | | // onBeforeRouteUpdate((to, from, next) => { |
| | | // if (to.path !== "/yhgl") { |
| | |
| | | } |
| | | }); |
| | | const selectValue = ref("孙胡沟"); |
| | | |
| | | const selectValue1 = ref("北京市"); |
| | | |
| | | const BJoptions = ref([]); |
| | | |
| | | const options = ref([ |
| | | { |
| | |
| | | |
| | | onMounted(() => { |
| | | handleCleanup(); |
| | | initeWaterPrimitiveView(); |
| | | // initeWaterPrimitiveView(); |
| | | // 默认先检查一遍数据 |
| | | if (simStore.DangerPoint && simStore.DangerPoint.length > 0) { |
| | | filterDataByArea("孙胡沟"); |
| | |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | .loading-overlay { |
| | | position: absolute; |
| | | top: 120px; |
| | | left: 0px; |
| | | right: 0px; |
| | | bottom: 10px; |
| | | background-color: rgba(47, 44, 44, 0.5); |
| | | /* 半透明遮罩 */ |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .spinner { |
| | | width: 40px; |
| | | height: 40px; |
| | | border: 4px solid #fff; |
| | | border-top: 4px solid transparent; |
| | | border-radius: 50%; |
| | | animation: spin 1s linear infinite; |
| | | } |
| | | |
| | | @keyframes spin { |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .district { |
| | | position: absolute; |
| | | width: 345px; |
| | |
| | | .district-content { |
| | | padding: 10px; |
| | | box-sizing: border-box; |
| | | height: calc(100% - 70px); |
| | | position: relative; |
| | | } |
| | | |
| | | .district-item-icon { |
| | |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | } |
| | | .loading-overlay { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | // background-color: rgba(0, 0, 0, 0.7); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | z-index: 100; |
| | | // border-radius: 4px; |
| | | } |
| | | |
| | | .loading-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | color: #fff; |
| | | } |
| | | |
| | | .loading-icon { |
| | | font-size: 24px; |
| | | margin-bottom: 8px; |
| | | animation: rotating 2s linear infinite; |
| | | } |
| | | |
| | | .loading-text { |
| | | color: white; |
| | | font-size: 14px; |
| | | text-align: center; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | @keyframes rotating { |
| | | 0% { |
| | | transform: rotate(0deg); |
| | | } |
| | | 100% { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | /deep/ .el-select__placeholder { |
| | |
| | | <p> |
| | | 方案状态 : |
| | | <span style="color: aquamarine"> |
| | | {{ item.result === -1 ? "出错" : item.result || "创建仿真" }} |
| | | {{ item.result === "-1" ? "出错" : item.result || "创建仿真" }} |
| | | </span> |
| | | <!-- <span style="color: aquamarine">{{ item.result || "创建仿真" }}</span> --> |
| | | <!-- <span style="color: aquamarine">{{ |
| | |
| | | } |
| | | } |
| | | |
| | | const flyToHomeView = () => { |
| | | const view = { |
| | | destination: { |
| | | x: -2355432.569004413, |
| | | y: 4687573.191838412, |
| | | z: 4098726.315265574, |
| | | }, |
| | | orientation: { |
| | | pitch: -0.9541030830183503, |
| | | roll: 0.00031421159527500464, |
| | | heading: 6.140424766644804, |
| | | }, |
| | | }; |
| | | viewer.scene.camera.flyTo(view); |
| | | } |
| | | |
| | | const startYHGL = () => { |
| | | init() |
| | | flyToHomeView() |
| | | locationShow.value = true |
| | | } |
| | | |
| | |
| | | EventBus.on("select-geom", ({ geom, flyHeight, shouldShowFill }) => { |
| | | flyToHeight.value = flyHeight; |
| | | ShowFill.value = shouldShowFill; |
| | | console.log(ShowFill.value, "ShowFill.valueShowFill.value"); |
| | | const coordsStr = geom |
| | | .replace("MULTIPOLYGON(((", "") // 去掉开头 |
| | | .replace(")))", ""); // 去掉结尾 |
| | |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | const validPaths = ["/", "/yhgl"]; |
| | | watch( |
| | | () => route.fullPath, |
| | | (val) => { |
| | | if (val != "/") { |
| | | if (!validPaths.includes(val)) { |
| | | // clusterLayer.dataSource.show = false |
| | | htmlEntityList.forEach((item) => { |
| | | item.show = false; |
| | |
| | | |
| | | const route = useRoute(); |
| | | const simStore = useSimStore(); |
| | | const backHome = ref(false); |
| | | |
| | | // 接收来自 ComponentA 的事件,并更新 isFlying |
| | | function handleBackToHome() { |
| | |
| | | <div class="screen-widget-text"> |
| | | {{ weather.now.text }} {{ weather.now.temperature + "℃" }} |
| | | </div> |
| | | <div |
| | | <!-- <div |
| | | class="screen-widget-time screen-widget-text" |
| | | style="margin-left: 20px" |
| | | > |
| | | {{ $dayjs().format("YYYY/MM/DD HH:mm") }} |
| | | </div> --> |
| | | <div |
| | | class="screen-widget-time screen-widget-text" |
| | | style="margin-left: 20px" |
| | | > |
| | | {{ currentTime }} |
| | | </div> |
| | | </div> |
| | | <div class="screen-widget-home"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, computed, defineEmits } from "vue"; |
| | | import { ref, onMounted, computed, defineEmits,onBeforeUnmount } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | import dayjs from 'dayjs' |
| | | |
| | | const currentTime = ref(dayjs().format("YYYY/MM/DD HH:mm:ss")); |
| | | |
| | | const updateTime = () => { |
| | | currentTime.value = dayjs().format("YYYY/MM/DD HH:mm:ss"); |
| | | }; |
| | | |
| | | let timer; |
| | | |
| | | onMounted(() => { |
| | | timer = setInterval(updateTime, 1000); |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | clearInterval(timer); // 避免内存泄漏 |
| | | }); |
| | | |
| | | const router = useRouter(); |
| | | const bgVisible = ref(true); |
| | | const defaultCity = ref(cityData.name); |
| | |
| | | .then((response) => response.json()) |
| | | .then((data) => { |
| | | weather.value = data.results[0]; |
| | | // console.log(weather.value) |
| | | }); |
| | | }; |
| | | function initScene() { |
| | |
| | | viewer.scene.camera.flyTo(view); |
| | | } |
| | | onMounted(() => { |
| | | // getWeatherData() |
| | | getWeatherData() |
| | | }); |
| | | </script> |
| | | <style lang="less" scoped> |
| | |
| | | <template> |
| | | <div class="navigation"> |
| | | <div class="navigation-contents" v-show="!simBtn"> |
| | | <div |
| | | class="navigation-item bg1" |
| | | :class="{ 'bg1-active': currentIndexs == 1 }" |
| | | @click="handleClickHome(1)" |
| | | > |
| | | 综合展示 |
| | | </div> |
| | | <div |
| | | class="navigation-item bg2" |
| | | :class="{ 'bg2-active': currentIndexs == 2 }" |
| | | @click="handleClickHome(2)" |
| | | style="margin-left: 15%" |
| | | > |
| | | 模拟仿真 |
| | | </div> |
| | | </div> |
| | | <div class="navigation-content" v-show="simBtn"> |
| | | <div class="navigation-content"> |
| | | <div |
| | | class="navigation-item bg1" |
| | | :class="{ 'bg1-active': currentIndex == 1 }" |
| | |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { ref,watch} from "vue"; |
| | | |
| | | const simBtn = ref(false); |
| | | const currentIndexs = ref(1); |
| | | const router = useRouter(); |
| | | const simStore = useSimStore(); |
| | |
| | | () => simStore.backToHome, |
| | | (newValue) => { |
| | | if (newValue) { |
| | | simBtn.value = false; |
| | | simStore.setBackToHome(false); |
| | | } |
| | | } |
| | | ); |
| | | const handleClickHome = (index) => { |
| | | if (index === 1) { |
| | | router.push("/"); |
| | | } else { |
| | | simBtn.value = true; |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | |
| | | <template> |
| | | <!-- <GisView /> --> |
| | | <Location /> |
| | | <Legend class="legend" /> |
| | | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import Location from "@/components/menu/Location.vue" |
| | | import Location from "@/components/menu/Location.vue"; |
| | | import Legend from "@/components/tools/Legend_yhgl.vue"; |
| | | |
| | | import GisView from "./GisView.vue"; |
| | | </script> |
| | | <style lang="less" scoped> |
| | | .legend { |