智慧园区前端大屏
shuishen
2025-08-06 3b10270c0dcc71faef1a67ea74971f2f29dc202a
周边检索及突发事件模拟调整
1 files modified
4 files added
568 ■■■■■ changed files
src/views/pd/components/dynamicPanel.vue 29 ●●●● patch | view | raw | blame | history
src/views/rim/components/box/dataContent.vue 369 ●●●●● patch | view | raw | blame | history
src/views/rim/components/leftContainer.vue 34 ●●●●● patch | view | raw | blame | history
src/views/rim/components/rightContainer.vue 107 ●●●●● patch | view | raw | blame | history
src/views/rim/index.vue 29 ●●●●● patch | view | raw | blame | history
src/views/pd/components/dynamicPanel.vue
@@ -2,15 +2,15 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2024-11-09 15:41:35
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-02-12 20:00:22
 * @FilePath: \bigScreen\src\views\pd\components\dynamicPanel.vue
 * @LastEditTime: 2025-08-06 00:09:39
 * @FilePath: \jsProject\bigScreen\src\views\pd\components\dynamicPanel.vue
 * @Description: 
 * 
 * Copyright (c) 2024 by shuishen, All Rights Reserved. 
-->
<script setup>
import EventBus from 'utils/bus'
import qysgwslx from "@/assets/json/qysgwslx"
const { VITE_APP_BASE } = import.meta.env
const emit = defineEmits(['closePanel'])
@@ -103,6 +103,7 @@
let dynamicVectorLayer = new DC.VectorLayer('dynamicVectorLayer').addTo(window.$viewer)
let dynamicHtmlLayer = new DC.HtmlLayer('dynamicHtmlLayer').addTo(window.$viewer)
let dynamicLineVectorLayer = new DC.VectorLayer('dynamicLineVectorLayer').addTo(window.$viewer)
let qyWsLayer = new DC.VectorLayer('qyWsLayer').addTo(window.$viewer)
let modelPosition = [
  {
@@ -523,6 +524,8 @@
EventBus.on('wxEntityClick', wxEntityClick)
const schemeStart = (item, type) => {
  emit('closePanel')
  clearAll()
@@ -534,6 +537,17 @@
      EventBus.emit('restHandleDelChange', `4-3`)
      EventBus.emit('restHandleDelChange', `4-9`)
    }
        // let polyline = new DC.Polyline(qysgwslx.features[0].geometry.coordinates.join(';'))
        // polyline.setStyle({
        //     width: 5,
        //     material: new DC.PolylineTrailMaterialProperty({
        //         color: DC.Color.RED,
        //         speed: 10
        //     }),
        //     clampToGround: true
        // })
        // qyWsLayer.addOverlay(polyline)
    if (item.showModel) {
      window.$viewer.flyToPosition("115.10587903,27.28374884,400,0,-90", () => {
@@ -642,9 +656,10 @@
    // }
  })
  dynamicVectorLayer.clear()
  dynamicHtmlLayer.clear()
  dynamicLineVectorLayer.clear()
    dynamicVectorLayer?.clear()
    dynamicHtmlLayer?.clear()
    dynamicLineVectorLayer?.clear()
    qyWsLayer?.clear()
}
onUnmounted(() => {
@@ -663,12 +678,14 @@
  dynamicVectorLayer && window.$viewer && window.$viewer.removeLayer(dynamicVectorLayer)
  dynamicHtmlLayer && window.$viewer && window.$viewer.removeLayer(dynamicHtmlLayer)
  dynamicLineVectorLayer && window.$viewer && window.$viewer.removeLayer(dynamicLineVectorLayer)
    qyWsLayer && window.$viewer && window.$viewer.removeLayer(qyWsLayer)
  tc = null
  track = null
  dynamicVectorLayer = null
  dynamicHtmlLayer = null
  dynamicLineVectorLayer = null
    qyWsLayer = null
})
</script>
src/views/rim/components/box/dataContent.vue
New file
@@ -0,0 +1,369 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-13 14:54:26
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-08-06 00:07:03
 * @FilePath: \jsProject\bigScreen\src\views\rim\components\box\dataContent.vue
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<script setup>
const { VITE_APP_BASE } = import.meta.env
import { Search, Refresh, Download } from '@element-plus/icons-vue'
import { useMap } from 'store/map'
import EventBus from 'utils/bus'
import { getEmePool, getNearbySupplies } from "@/api/base"
import { nextTick, onBeforeUnmount, onUnmounted, reactive, watch } from "vue"
const store = useMap()
const loading = ref(false)
const TableContent = ref(null)
const curTableHeight = ref(0)
const regionVal = ref(100)
const panoramaShow = ref(false)
const panoramaTitle = ref('')
const panoramaUrl = ref('')
const tableData = ref([])
const typeList = [
    {
        type: 1,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/yjc.png',
        className: 'yjc-box',
    },
    {
        type: 2,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/yjc.png',
        className: 'yjc-box',
    },
    {
        type: 3,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/ysf.png',
        className: 'ysf-box',
    },
    {
        type: 4,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/zb.png',
        className: 'sk-box',
    },
    {
        type: 5,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/sd.png',
        className: 'xfs-box',
    },
    {
        type: 6,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/kt.png',
        className: 'sk-box',
    },
    {
        type: 8,
        backgroundIcon: VITE_APP_BASE + 'img/mapicon/ql.png',
        className: 'xfs-box',
    },
]
let yjwzImg = VITE_APP_BASE + 'img/mapicon/yjwz.png'
onMounted(() => {
    curTableHeight.value = TableContent.value.offsetHeight
    EventBus.emit('flyToyqfw', 'flyToyqfw')
    EventBus.emit('destroyPop', 'destroyPop')
})
const searchClick = () => {
    getLists()
}
const tabList = ref([
    {
        ind: 0,
        title: '应急空间',
        select: false,
    },
    {
        ind: 1,
        title: '应急物资',
        select: false,
    }
])
const curTabInd = ref(0)
const tabClick = (item) => {
    tabList.value.forEach(i => i.select = false)
    item.select = true
    curTabInd.value = item.ind
    getLists()
}
let addTileLayers = null
// 查询分页数据
const getLists = () => {
    loading.value = true
    tableData.value = []
    if (!addTileLayers) {
        addTileLayers = new DC.HtmlLayer('addTileLayers')
        window.$viewer.addLayer(addTileLayers)
    } else {
        addTileLayers.clear()
    }
    if (curTabInd.value === 1) {
        getNearbySupplies({
            distance: regionVal.value,
            latitude: store.rimPosition.lat.toFixed(6),
            longitude: store.rimPosition.lng.toFixed(6)
        })
            .then((res) => {
                const data = res.data.data
                data.filter(i => i.lng && i.lng != '' && i.lat && i.lat != '').forEach(i => {
                    i.panoramicUrl = i.url
                    if (i.type === 2) {
                        let iconEl = `
                            <div class="map-name">${i.name}</div>
                                <div class="map-icon">
                                <img src="${yjwzImg}">
                            </div>
                            `
                        let divIcon = new DC.DivIcon(
                            new DC.Position(i.lng, i.lat, i.ele || 64),
                            `<div class="public-map-popup  qyfb-box yjwz-height-box ">
                                ${iconEl}
                            </div>`
                        )
                        divIcon.attrParams = i
                        let incident = (e) => {
                            const { attrParams } = e.overlay
                            if (
                                attrParams.panoramicUrl && attrParams.panoramicUrl.length > 0
                            ) {
                                panoramaTitle.value = attrParams.name
                                panoramaUrl.value = attrParams.panoramicUrl
                                panoramaShow.value = true
                                return
                            }
                        }
                        divIcon.on(DC.MouseEventType.CLICK, incident)
                        addTileLayers.addOverlay(divIcon)
                    }
                })
                tableData.value = data
                loading.value = false
            })
            .catch((err) => {
                loading.value = false
                console.log(err)
            })
    } else {
        getEmePool({
            distance: regionVal.value,
            latitude: store.rimPosition.lat.toFixed(6),
            longitude: store.rimPosition.lng.toFixed(6)
        })
            .then((res) => {
                const data = res.data.data
                data.filter(i => i.lng && i.lng != '' && i.lat && i.lat != '').forEach(i => {
                    i.firmName = i.firmName ? i.firmName : '瑞昌工业园'
                    let iconEl = ''
                    let divclassName = ''
                    let flag = typeList.find(l => l.type == i.type)
                    if (flag) {
                        divclassName = flag.className
                        if (flag.backgroundIcon) {
                            iconEl = `
                        <div class="map-name">${i.name}</div>
                        <div class="map-icon">
                            <img src="${flag.backgroundIcon}">
                        </div>
                        `
                        }
                        let divIcon = new DC.DivIcon(
                            new DC.Position(i.lng, i.lat, i.ele || 64),
                            `<div class="public-map-popup ${divclassName}">
                            ${iconEl}
                        </div>`
                        )
                        divIcon.attrParams = i
                        addTileLayers.addOverlay(divIcon)
                    }
                })
                tableData.value = data
                loading.value = false
            })
            .catch((err) => {
                loading.value = false
                console.log(err)
            })
    }
}
nextTick(() => {
    tabClick(tabList.value[0])
})
watch(() => store.rimPosition, () => {
    getLists()
})
const closePanoramaPopup = () => {
    panoramaShow.value = false
}
onBeforeUnmount(() => {
    if (addTileLayers) {
        addTileLayers.clear()
        window.$viewer && window.$viewer.removeLayer(addTileLayers)
        addTileLayers = null
    }
})
// 行点击
function rowClick (row, column, event) {
    if (row.lng && row.lat) {
        window.$viewer.flyToPosition(new DC.Position(row.lng, row.lat, 600, 0, -90, 0))
    }
}
</script>
<template>
    <div class="w100 h0 flex-1 flex f-d-c cur-container">
        <div class="location">
            <div class="point-box"><span>经度:</span><span>{{ store.rimPosition.lng.toFixed(6) }}</span></div>
            <div class="point-box"><span>纬度:</span><span>{{ store.rimPosition.lat.toFixed(6) }}</span></div>
            <div class="set-region">
                <span>范围:</span>
                <span>
                    <el-input v-model="regionVal" type="number" :size="'small'" placeholder="请输入范围" />m
                </span>
            </div>
            <div class="btn">
                <el-button :type="'primary'" :size="'small'" :icon="Search" @click="searchClick">
                </el-button>
            </div>
        </div>
        <div class="tab-list">
            <div :class="{ active: item.select }" v-for="item, index in tabList" :key="index" @click="tabClick(item)">{{
                item.title }}</div>
        </div>
        <!-- <global-search :options="options" @searchBtn="searchBtn" @resetBtn="resetBtn" ref="SeachBarCondition"></global-search> -->
        <div class="h0 flex-1 table-content" ref="TableContent" v-loading="loading"
            element-loading-background="rgba(46, 81, 136, 0.9)">
            <el-table empty-text="暂无数据" @row-click="rowClick" border :data="tableData" :height="curTableHeight"
                style="width: 100%">
                <el-table-column align="center" label="ID" width="42" prop="rank">
                    <template #default="{ $index, row }">
                        {{ $index + 1 }}
                    </template>
                </el-table-column>
                <el-table-column align="center" show-overflow-tooltip prop="firmName" label="企业名称" />
                <el-table-column align="center" show-overflow-tooltip prop="name" label="名称" />
            </el-table>
        </div>
        <panorama v-show="panoramaShow" :title="panoramaTitle" :url="panoramaUrl"
            @closePanoramaPopup="closePanoramaPopup">
        </panorama>
    </div>
</template>
<style lang="scss" scoped>
.el-form-item__label {
    color: #fff !important;
}
.table-content {
    flex-basis: auto;
    height: calc(100% - 40px);
}
.cur-container {
    color: #fff;
    .location {
        padding: 4px 6px;
        display: flex;
        gap: 4px;
        .point-box {
            flex: 1;
        }
        .set-region {
            display: flex;
            width: 112px;
            span {
                display: flex;
                white-space: nowrap;
            }
            ::v-deep(.el-input) {
                .el-input__wrapper {
                    background: rgba(135, 158, 199, 0.2);
                    box-shadow: inset 0px 3px 7px 0px rgba(42, 138, 236, 0.949);
                    border-radius: 4px 4px 4px 4px;
                    border: 1px solid #4081CB;
                }
                input {
                    color: #D4E8F8;
                }
            }
        }
        ::v-deep(.el-button) {
            background: #277DFF;
            border-color: #277DFF;
            &.reset-btn {
                color: #D4E8F8;
                background: #43779B;
                border-color: #43779B;
            }
        }
        div {
            display: flex;
        }
    }
    .tab-list {
        margin: 8px 6px;
        display: flex;
        >div {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            background: rgb(103, 135, 214) !important;
            line-height: 32px;
            cursor: pointer !important;
            &.active {
                background: #409eff !important;
            }
        }
    }
}
</style>
src/views/rim/components/leftContainer.vue
New file
@@ -0,0 +1,34 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-07-31 20:22:33
 * @FilePath: \bigScreen\src\views\rim\components\leftContainer.vue
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<script setup>
import dataContent from './box/dataContent.vue'
</script>
<template>
    <div class="left-container">
        <div class="data box h0 flex-1">
            <title-box>
                <template #titleName>
                    周边检索
                </template>
            </title-box>
            <div class="content-box">
                <data-content></data-content>
            </div>
        </div>
    </div>
</template>
<style lang="scss" scoped>
.left-container {
    width: 444px;
}
</style>
src/views/rim/components/rightContainer.vue
New file
@@ -0,0 +1,107 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2024-12-03 13:23:28
 * @FilePath: \bigScreen\src\views\rs\components\leftContainer.vue
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<script setup>
import EventBus from 'utils/bus'
import { getDictionary } from "@/api/dict/dict"
import { nextTick, onUnmounted, reactive } from 'vue'
const resData = reactive({
    data: [
        {
            label: '一般',
            value: 1
        },
        {
            label: '较大',
            value: 2
        },
        {
            label: '暂定',
            value: 9
        }
    ]
})
const curSelect = ref('')
const tabClick = (item) => {
    if (curSelect.value) EventBus.emit('restHandleDelChange', `4-${curSelect.value}`)
    curSelect.value = item.value
    EventBus.emit('restHandleCheckChange', `4-${item.value}`)
    EventBus.emit('rsTabChange', item.value)
}
nextTick(() => {
    tabClick(resData.data[0])
})
const showOn = computed(() => (item) => {
    if (curSelect.value == item.value) {
        return true
    }
    return false
})
onUnmounted(() => {
    if (curSelect.value) EventBus.emit('restHandleDelChange', `4-${curSelect.value}`)
})
</script>
<template>
    <div class="right-container cur-container">
        <div class="tablist h100">
            <div class="cursor-p" :class="{ on: showOn(item) }" v-for="item, index in resData.data" :key="index"
                @click="tabClick(item)">
                <div class="label-box">
                    {{ item.label }}
                </div>
            </div>
        </div>
    </div>
</template>
<style lang="scss" scoped>
.cur-container {
    background: transparent;
    pointer-events: none;
    .tablist {
        pointer-events: all;
        &>div {
            display: flex;
            align-items: center;
            justify-content: center;
            margin-top: 16px;
            padding: 10px;
            width: 64px;
            height: 64px;
            border-radius: 50%;
            box-shadow: inset 0 0 40px #409eff;
            color: #fff;
            box-sizing: content-box;
            &.on {
                position: relative;
                color: #75b1ff;
            }
            .label-box {
                line-height: 24px;
                text-align: center;
            }
        }
    }
}
</style>
src/views/rim/index.vue
New file
@@ -0,0 +1,29 @@
<!--
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2023-03-10 15:27:59
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-07-31 19:51:55
 * @FilePath: \bigScreen\src\views\rim\index.vue
 * @Description: 综合设计
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
-->
<script setup>
import leftContainer from './components/leftContainer.vue'
import rightContainer from './components/rightContainer.vue'
</script>
<template>
    <div class="container page-container">
        <left-container></left-container>
        <!-- <right-container></right-container> -->
    </div>
</template>
<style lang="scss" scoped>
.container {
    position: absolute;
    width: 100%;
    height: 100%;
}
</style>