| src/api/dataCenter/dataCenter.js | ●●●●● patch | view | raw | blame | history | |
| src/assets/images/dataCenter/datamap/activeevent.png | patch | view | raw | blame | history | |
| src/assets/images/dataCenter/datamap/eventCompleted.png | patch | view | raw | blame | history | |
| src/assets/images/dataCenter/datamap/popUpBox.png | patch | view | raw | blame | history | |
| src/hooks/components/EventPopUpBox.vue | ●●●●● patch | view | raw | blame | history | |
| src/views/dataCenter/components/dataCenterMap.vue | ●●●●● patch | view | raw | blame | history | |
| src/views/dataCenter/dataCenter.vue | ●●●●● patch | view | raw | blame | history |
src/api/dataCenter/dataCenter.js
New file @@ -0,0 +1,8 @@ import request from '@/axios'; export const getaiImagesPage = (data) => { return request({ url: `/blade-resource/attach/aiImagesPage`, method: 'post', data }) }; src/assets/images/dataCenter/datamap/activeevent.png
src/assets/images/dataCenter/datamap/eventCompleted.png
src/assets/images/dataCenter/datamap/popUpBox.png
src/hooks/components/EventPopUpBox.vue
New file @@ -0,0 +1,142 @@ <template> <div class="mapPopUpBox"> <div class="title"> <span>222</span> <el-icon class="header-close" @click.stop="props.removeLabel"> <Close /> </el-icon> </div> <div class="content"> <div class="medium"> <el-image class="eventImage" :src="infoList?.smallUrl" :preview-src-list="[infoList?.smallUrl]" fit="cover" preview-teleported ></el-image> </div> <div class="details"> <div class="label">时间:</div> <div class="value point"> 11 </div> <div class="label">地点:</div> <div class="value"> 22 </div> </div> </div> </div> </template> <script setup> import { ElImage, ElIcon } from 'element-plus' import { Close } from '@element-plus/icons-vue' // import { getEventDetails } from '@/api/home/aggregation' import _ from 'lodash' import { getSmallImg } from '@/utils/util' const props = defineProps(['data', 'removeLabel']) const loading = ref(true) const info = ref({ event_name: '', status: 1, url: '1', longitude: '', latitude: '', create_time: '04/01 12:41', }) const infoList = props.data onMounted(async () => {}) const disposeUrl = ({ url }) => { return getSmallImg(url) } </script> <style scoped lang="scss"> .mapPopUpBox { width: 271px; height: 173px; background: url('@/assets/images/dataCenter/datamap/popUpBox.png') no-repeat center / 100% 100%; padding: 13px 15px; pointer-events: all; .title { font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif; font-weight: 400; font-size: 18px; line-height: 16px; background: linear-gradient(180deg, #a8e5fb 0%, #e6f8ff 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; -moz-background-clip: text; -moz-text-fill-color: transparent; background-clip: text; text-fill-color: transparent; margin-bottom: 10px; display: flex; align-items: center; justify-content: space-between; .header-close { width: 20px; height: 100%; line-height: 100%; display: flex; align-items: center; color: #9cd5ff; pointer-events: all; cursor: pointer; } } .content { height: 102px; width: 240px; display: flex; align-items: center; .medium { height: 102px; width: 120px; margin-right: 10px; > img, video, div { width: 100%; height: 100%; } } .details { .label { font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; color: #7babd7; line-height: 16px; margin-bottom: 2px; } .value { font-family: Source Han Sans CN, Source Han Sans CN; font-weight: 400; font-size: 14px; color: #d8edff; line-height: 16px; margin-bottom: 2px; } .point { margin-bottom: 14px; } } } } </style> src/views/dataCenter/components/dataCenterMap.vue
New file @@ -0,0 +1,210 @@ <template> <el-dialog modal-class="mapDialog" v-model="isShow" width="80%"> <div class="mapBox"> <div id="dataCenterMap" class="ztzf-cesium"></div> </div> </el-dialog> </template> <script setup> import { useStore } from 'vuex'; import { PublicCesium } from '@/utils/cesium/publicCesium'; import { Cartesian3 } from 'cesium'; import * as Cesium from 'cesium'; import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'; import { render } from 'vue'; import defaultIcon from '@/assets/images/dataCenter/datamap/eventCompleted.png'; const isShow = defineModel('show'); const viewerRef = shallowRef(null); let viewer = null; const viewInstance = shallowRef(null); const store = useStore(); const currentAreaPosition = ref({ height: 1987280, latitude: 27.636112, longitude: 115.732975 }); let handler = null; // 获取弹框box const createLabelDom = data => { console.log('data',data); const vNode = h(EventPopUpBox, { data, removeLabel }) const tooltipContainer = document.createElement('div') tooltipContainer.id = 'mapPopUpBox' tooltipContainer.style.position = 'absolute' tooltipContainer.style.transform = 'translate(-50%,-135%)' tooltipContainer.style.pointerEvents = 'none' document.querySelector('#dataCenterMap').append(tooltipContainer) render(vNode, tooltipContainer) return tooltipContainer }; let currentClickEntity = null; // 弹框位置刷新 const labelBoxUpdate = () => { if (!currentClickEntity) return; const mapPopUpBox = document.querySelector('#mapPopUpBox'); let dom = mapPopUpBox ? mapPopUpBox : createLabelDom(currentClickEntity.properties.customData._value.data); const screenPosition = viewer?.scene.cartesianToCanvasCoordinates( currentClickEntity?.position?._value ); if (screenPosition) { dom.style.left = `${screenPosition.x}px`; dom.style.top = `${screenPosition.y}px`; dom.style.display = 'block'; } }; const removeDom = () => { const dom = document.querySelector('#mapPopUpBox'); if (dom && dom.parentNode) { dom.parentNode.removeChild(dom); } }; // 移除弹框标签 const removeLabel = () => { viewer?.scene.postRender.removeEventListener(labelBoxUpdate); removeDom(); }; // 左键单机事件 const singleMachineEvent = async click => { let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id); if (!clickedEntities.length) return; currentClickEntity = clickedEntities[0]; removeLabel(); viewer.scene.postRender.addEventListener(labelBoxUpdate); }; // 事件初始化 const handlerInit = () => { if (handler) return; handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas); handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK); }; const removeHandler = () => { handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); handler?.destroy(); handler = null; }; const dataPointList = [ { longitude: '115.85708286111111', latitude: '28.62837602777778', }, { longitude: '115.8566981111111', latitude: '28.624613027777777', }, { longitude: '115.85474438888889', latitude: '28.624930444444445', }, { longitude: '115.85518375', latitude: '28.62479547222222', }, ]; function renderDataPoint() { dataPointList.forEach((item, index) => { const sizeObj = { width: 30, height: 30 }; viewer.entities.add({ id: `renderDataPoint-${index}`, position: Cesium.Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude)), label: { font: '12pt Source Han Sans CN', fillColor: Cesium.Color.WHITE, outlineColor: Cesium.Color.BLACK, outlineWidth: 2, style: Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, pixelOffset: new Cesium.Cartesian2(0, -9), }, billboard: { image: defaultIcon, ...sizeObj, }, properties: { customData: { data: item, }, }, }); }); } const initMap = () => { const publicCesiumInstance = new PublicCesium({ dom: 'dataCenterMap', flatMode: false, terrain: false, mapFilter: true, }); viewerRef.value = publicCesiumInstance.getViewer(); viewer = publicCesiumInstance.getViewer(); const { longitude, latitude, height } = currentAreaPosition.value; const position = Cartesian3.fromDegrees(longitude, latitude, height); viewerRef.value.camera.flyTo({ duration: 0, destination: position, orientation: { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-90.0), roll: 0.0, }, }); viewInstance.value = publicCesiumInstance; }; // 监听对话框状态 watch(isShow, (newVal) => { if (newVal) { nextTick(() => { initMap(); handlerInit(); renderDataPoint(); }); } else { // 对话框关闭时清理资源 viewInstance.value?.viewerDestroy(); removeHandler(); } }); onMounted(() => { nextTick(() => { initMap(); handlerInit(); renderDataPoint(); }); }); onBeforeUnmount(() => { viewInstance.value?.viewerDestroy(); removeHandler(); }); </script> <style > .mapDialog .el-dialog__body { height: 700px !important; padding: 0 !important; } </style> <style scoped lang="scss"> .mapBox { z-index: 2; height: 650px; width: 98%; position: absolute; left: 13px; top: 50px; #dataCenterMap { width: 100%; height: 100%; } } </style> src/views/dataCenter/dataCenter.vue
@@ -49,7 +49,7 @@ <span class="delete" @click="deleteDetail()" v-if="scope.row.fileformat !== 'AI识别'" >删除</span > <span class="location" v-if="scope.row.fileformat !== '视频'">定位</span> <span class="location" @click="positionDetail()" v-if="scope.row.fileformat !== '视频'">定位</span> </template> </el-table-column> </el-table> @@ -133,15 +133,19 @@ <video style="width:100%" class="videoBox" ref="videoRefs" controls autoplay :src="currentVideoUrl"></video> </div> </el-dialog> <!-- 地图弹框 --> <dataCenterMap v-model:show="dataCenterMapVisible"></dataCenterMap> </div> </template> <script setup> import dataCenterMap from '@/views/dataCenter/components/dataCenterMap.vue' import PanoramaPopup from '@/components/PanoramaPopup/PanoramaPopup.vue'; //全景 import { ElMessage, ElMessageBox } from 'element-plus'; import searchData from '@/views/dataCenter/components/searchData.vue'; import fy1 from '@/assets/images/dataCenter/1.jpeg'; import {getaiImagesPage} from '@/api/dataCenter/dataCenter' import { onMounted } from 'vue'; function convertVideoUrlToThumbnail(videoUrl) { // 检查是否是有效的视频URL if (!videoUrl || typeof videoUrl !== 'string') { @@ -151,6 +155,7 @@ const thumbnailUrl = videoUrl.replace(/\.mp4$/, '_small.jpg'); return thumbnailUrl; } const jobListParams = reactive({ current: 1, size: 10, @@ -213,6 +218,13 @@ fileformat: '正射', }, ]; // 获取列表数据 const getgetaiImagesPage =()=>{ getaiImagesPage(jobListParams).then(res=>{ console.log('res',res); }) } const handleSizeChange = () => {}; const handleCurrentChange = () => {}; // 多选 @@ -260,6 +272,16 @@ currentVideoUrl.value = val.img; console.log('视频', val); }; // 地图弹框 const dataCenterMapVisible = ref(false) const positionDetail=()=>{ console.log('地图'); dataCenterMapVisible.value = true } onMounted(()=>{ // getgetaiImagesPage() }) </script> <style scoped lang="scss">