7 files modified
1 files added
| | |
| | | return request({ |
| | | url: `/drone-device-core/manage/api/v1/devices/getFlyingNestBy?current=${data.page}&size=${data.limit}`, |
| | | method: 'post', |
| | | data: { |
| | | wayline_id: data.wayline_id, |
| | | type: data.type |
| | | }, |
| | | data |
| | | }) |
| | | } |
| | | |
| | |
| | | import { set } from 'lodash' |
| | | import { EDeviceTypeName } from '@/utils/staticData/enums' |
| | | import { getStore, setStore } from '@/utils/store' |
| | | |
| | | const home = { |
| | | state: { |
| | | machineNestDetail: false, // 机巢详情 |
| | | machineNestDetail: false, // 机巢长列表 |
| | | isEventOverviewDetail: false,//是事件概述详情 |
| | | // 用户行政区划中心点 |
| | | userAreaPosition: getStore({ name: 'userAreaPosition' }) || {}, |
| | | // 用户切换后行政区划中心点 |
| | | currentAreaPosition:getStore({ name: 'currentAreaPosition' }) || {}, |
| | | singleUavHome: {}, |
| | | footActiveIndex: 0, |
| | | isEventOverviewDetail: false,//是事件概述详情 |
| | | singleTotal: {}, // 统计单个机巢数据 |
| | | // 项目id |
| | | selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'), |
| New file |
| | |
| | | <template> |
| | | <div class="AINowFly"> |
| | | <div>智引即飞</div> |
| | | <div> |
| | | 任务名称 |
| | | <el-input type="text" v-model="params.taskName" /> |
| | | </div> |
| | | <div> |
| | | 关联算法: |
| | | <el-select v-model="params.ai_types" placeholder="请选择"> |
| | | <el-option v-for="item in taskAlgorithm" :key="item.id" :label="item.dictValue" :value="item.dictKey" /> |
| | | </el-select> |
| | | </div> |
| | | <div> |
| | | 地址: |
| | | <el-input type="text" v-model="params.dz" /> |
| | | </div> |
| | | <el-table :data="list"> |
| | | <el-table-column type="index" label="序号" /> |
| | | <el-table-column prop="nickname" label="机巢名称" /> |
| | | <el-table-column prop="minute" label="预计飞行时长(分钟)" /> |
| | | <el-table-column prop="exe_distance" label="预计飞行距离(m)" /> |
| | | </el-table> |
| | | </div> |
| | | </template> |
| | | <script setup> |
| | | import { getMultipleDictionary } from '@/api/system/dictbiz' |
| | | import * as Cesium from 'cesium' |
| | | import { getFlyingNestBy } from '@/api/home/task' |
| | | import { cartesian3Convert } from '@/utils/cesium/mapUtil' |
| | | import { Cartesian3 } from 'cesium' |
| | | import uavImg from '@/assets/images/home/useUavHome/uavImg.png' |
| | | import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial' |
| | | import lineImg from '@/assets/images/arrow-right-blue.png' |
| | | import _ from 'lodash' |
| | | import { ElMessage } from 'element-plus' |
| | | |
| | | const params = ref({ |
| | | taskName: '', |
| | | ai_types: '', |
| | | dz: '', |
| | | }) |
| | | let handler = null |
| | | const taskAlgorithm = ref([]) |
| | | |
| | | let viewer |
| | | const list = ref([]) |
| | | let eventPoint = {} |
| | | |
| | | const renderingLine = () => { |
| | | const { longitude, latitude } = eventPoint |
| | | list.value.forEach((item, index) => { |
| | | const start = Cartesian3.fromDegrees(Number(item.longitude), Number(item.latitude)) |
| | | const end = Cartesian3.fromDegrees(Number(longitude), Number(latitude)) |
| | | const positionsList = [start, end] |
| | | // 线 |
| | | viewer.entities.add({ |
| | | id: `AINow-line-${index}`, |
| | | polyline: { |
| | | width: 4, |
| | | positions: positionsList, |
| | | material: new ImageTrailMaterial({ |
| | | color: { alpha: 1, blue: 1, green: 1, red: 1 }, |
| | | speed: 20, |
| | | image: lineImg, |
| | | repeat: { x: Math.floor(40), y: 1 }, |
| | | }), |
| | | clampToGround: false, |
| | | }, |
| | | }) |
| | | // 点 |
| | | viewer.entities.add({ |
| | | id: `AINow-point-${index}`, |
| | | position: start, |
| | | label: { |
| | | text: item.nickname, |
| | | 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: new Cesium.ConstantProperty(uavImg), |
| | | width: 24, |
| | | height: 24, |
| | | }, |
| | | properties: { |
| | | customData: { |
| | | data: item, |
| | | }, |
| | | }, |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | const removeEntities = () => { |
| | | const entitiesIDs = viewer.entities.values.map(i => i.id) |
| | | entitiesIDs.forEach(item => { |
| | | item.includes('AINow-') && viewer.entities.removeById(item) |
| | | }) |
| | | } |
| | | |
| | | // 单击事件 |
| | | const singleClickEvent = click => { |
| | | removeEntities() |
| | | const earthPosition = viewer.scene.pickPosition(click.position) |
| | | viewer.entities.add({ |
| | | position: earthPosition, |
| | | id: `AINow-event-0`, |
| | | point: { |
| | | pixelSize: 10, |
| | | color: Cesium.Color.RED, |
| | | outlineColor: Cesium.Color.WHITE, |
| | | outlineWidth: 2, |
| | | }, |
| | | }) |
| | | const { longitude, latitude } = cartesian3Convert(earthPosition, viewer) |
| | | eventPoint = { longitude, latitude } |
| | | getFJList() |
| | | } |
| | | |
| | | // 请求字典字段 |
| | | const requestDictionary = () => { |
| | | getMultipleDictionary('SF').then(res => { |
| | | if (res.code !== 0) { |
| | | taskAlgorithm.value = res.data.data['SF'] |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 获取飞机列表 |
| | | const getFJList = async () => { |
| | | const params = { ...eventPoint, page: 1, limit: 9999, type: 1 } |
| | | const res = await getFlyingNestBy(params) |
| | | list.value = (res.data?.data || []).map(item => ({ |
| | | ...item, |
| | | minute: _.round(item.estimated_arrival_time / 60, 0), |
| | | })) |
| | | if (!list.value.length) ElMessage.warning('附近暂无可用无人机') |
| | | renderingLine() |
| | | } |
| | | |
| | | const initMap = () => { |
| | | handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas) |
| | | handler.setInputAction(singleClickEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK) |
| | | } |
| | | |
| | | const removeAll = () => { |
| | | removeEntities() |
| | | handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK) |
| | | handler?.destroy() |
| | | handler = null |
| | | } |
| | | |
| | | onBeforeUnmount(() => { |
| | | removeAll() |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | requestDictionary() |
| | | viewer = window.$viewer |
| | | initMap() |
| | | }) |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | .AINowFly { |
| | | position: absolute; |
| | | top: 200px; |
| | | right: 0; |
| | | width: 400px; |
| | | height: 700px; |
| | | background: white; |
| | | color: black; |
| | | font-size: 20px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="footer"> |
| | | <img |
| | | v-for="item in list" |
| | | v-for="(item,index) in list.filter(i => !i.disable)" |
| | | :class="item.className" |
| | | :src="item.active ? item.activeImg : item.img" |
| | | alt="" |
| | | @click="imgClick(item)" |
| | | @click="footAction(item,index)" |
| | | /> |
| | | </div> |
| | | <div class="intelligent-introduction-flying"> |
| | | <img class="orthophoto" src="@/assets/images/intelligent-introduction-flying.png" alt="" /> |
| | | <img |
| | | class="orthophoto" |
| | | src="@/assets/images/intelligent-introduction-flying.png" |
| | | alt="" |
| | | @click="footAction(list[5],5)" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | |
| | | import { useMapAggregation } from '@/views/Home/useMapAggregation/useMapAggregation' |
| | | import { useStore } from 'vuex' |
| | | import func from '@/utils/func' |
| | | |
| | | const store = useStore() |
| | | const footActiveIndex = computed(() => store.state.home.footActiveIndex) |
| | | |
| | | // 机巢聚合 |
| | | const { init, removeAll } = useMapAggregation('device') |
| | |
| | | |
| | | const list = ref([ |
| | | { |
| | | name: 'event1', |
| | | name: 'jc', |
| | | img: img1, |
| | | activeImg: activeImg1, |
| | | active: true, |
| | |
| | | removeAll: removeAll, |
| | | }, |
| | | { |
| | | name: 'event2', |
| | | name: 'sj', |
| | | img: img2, |
| | | activeImg: activeImg2, |
| | | active: false, |
| | |
| | | init: eventInit, |
| | | removeAll: eventRemove, |
| | | }, |
| | | { name: 'event3', img: img3, activeImg: activeImg3, active: false, className: 'panorama' }, |
| | | { name: 'event4', img: img4, activeImg: activeImg4, active: false, className: 'threeD' }, |
| | | { name: 'event5', img: img5, activeImg: activeImg5, active: false, className: 'orthophoto' }, |
| | | { name: 'qj', img: img3, activeImg: activeImg3, active: false, className: 'panorama' }, |
| | | { name: 'sw', img: img4, activeImg: activeImg4, active: false, className: 'threeD' }, |
| | | { name: 'zs', img: img5, activeImg: activeImg5, active: false, className: 'orthophoto' }, |
| | | { name: 'zyjf', active: false, disable: true }, |
| | | ]) |
| | | const store = useStore() |
| | | const imgClick = (toItem,index) => { |
| | | index !== undefined && store.commit('setFootActiveIndex',index) |
| | | const fromItem = list.value.find(item => item.active) |
| | | if (fromItem.name === toItem.name) return |
| | | |
| | | const footAction = (toItem, index) => { |
| | | const fromItem = list.value.find(item => item.active) //上一个激活item |
| | | if (fromItem.name === toItem?.name) return //是重复点击 |
| | | index !== undefined && store.commit('setFootActiveIndex', index) //是按钮点击得动作 |
| | | fromItem?.removeAll?.() |
| | | nextTick(() => { |
| | | toItem?.init?.() |
| | | }) |
| | | list.value = list.value.map(item => ({ ...item, active: item.name === toItem.name })) |
| | | nextTick(() => toItem?.init?.()) |
| | | list.value = list.value.map(item => ({ ...item, active: item.name === toItem?.name })) |
| | | } |
| | | |
| | | const footActiveIndex = computed(() => store.state.home.footActiveIndex) |
| | | watch(footActiveIndex, val => { |
| | | console.log(6666666) |
| | | imgClick(list.value[val]) |
| | | },{deep:true}) |
| | | watch( |
| | | footActiveIndex, |
| | | val => { |
| | | footAction(list.value[val]) |
| | | }, |
| | | { deep: true } |
| | | ) |
| | | |
| | | // 销毁前钩子 |
| | | onBeforeUnmount(() => { |
| | |
| | | bottom: 23px; |
| | | |
| | | img { |
| | | cursor: pointer; |
| | | width: 146px; |
| | | height: 54px; |
| | | } |
| | |
| | | <template> |
| | | <template v-if="singleUavHome?.device_sn"> |
| | | <SignMachineNest /> |
| | | </template> |
| | | <!-- 单个机巢页面--> |
| | | <SignMachineNest v-if="singleUavHome?.device_sn" /> |
| | | <!-- 事件概述详细信息页面--> |
| | | <EventOverviewDetail v-else-if="isEventOverviewDetail" /> |
| | | |
| | | <AINowFly v-else-if="isAINowFly" /> |
| | | <!-- 首页默认的页面--> |
| | | <template v-else> |
| | | <EventOverviewDetail v-if="isEventOverviewDetail" /> |
| | | <template v-else> |
| | | <SearchBox /> |
| | | <HomeLeft /> |
| | | <HomeRight /> |
| | | </template> |
| | | <HomeLeft /> |
| | | <HomeRight /> |
| | | </template> |
| | | |
| | | <SearchBox /> |
| | | <RSide /> |
| | | <Footer /> |
| | | </template> |
| | |
| | | import { onMounted } from 'vue' |
| | | import cesiumOperation from '@/utils/cesium-tsa' |
| | | import EventOverviewDetail from '@/views/Home/EventOverviewDetail/EventOverviewDetail.vue' |
| | | import AINowFly from '@/views/Home/AINowFly.vue' |
| | | |
| | | const store = useStore() |
| | | const { _init, viewerDestory } = cesiumOperation() |
| | | |
| | | const singleUavHome = computed(() => store.state.home.singleUavHome) |
| | | const isEventOverviewDetail = computed(() => store.state.home.isEventOverviewDetail) |
| | | const isAINowFly = computed(() => store.state.home.footActiveIndex === 5) |
| | | |
| | | onUnmounted(() => { |
| | | store.commit('setSingleUavHome', null) |
| | | console.log('home销毁') |
| | | store.commit('setIsEventOverviewDetail', false) |
| | | store.commit('setFootActiveIndex', 0) |
| | | viewerDestory() |
| | | }) |
| | | |
| | |
| | | <!-- 机巢概况 --> |
| | | <template> |
| | | <common-title :style="{ marginLeft: pxToRem(14) }" @details="detailsFun"></common-title> |
| | | <common-title title="机巢概况" :style="{ marginLeft: pxToRem(14) }" @details="detailsFun"></common-title> |
| | | <div class="overview-next"> |
| | | <MachineNestTotal @searchNickName="handleSearch" /> |
| | | <div class="table-list"> |
| | |
| | | border-radius: 0px 0px 0px 0px; |
| | | opacity: 0.85; |
| | | margin-bottom: 10px; |
| | | |
| | | |
| | | .table-list { |
| | | font-family: Source Han Sans CN, Source Han Sans CN; |
| | | margin: 16px; |
| | |
| | | id: `aggregation-splashed-${index}`, |
| | | position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude), |
| | | label: { |
| | | // 随机整数 |
| | | text: item.nickname, |
| | | font: '12pt Source Han Sans CN', |
| | | fillColor: Cesium.Color.WHITE, |
| | |
| | | }) |
| | | |
| | | needFly && viewer.flyTo(dataSource, { |
| | | offset: new Cesium.HeadingPitchRange( |
| | | 0, // heading: 0 (朝向不变) |
| | | Cesium.Math.toRadians(-60), // pitch: -90° (垂直向下) |
| | | 0 // range: 0 (默认距离) |
| | | ), |
| | | offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-60), 0), |
| | | duration: 0.5, |
| | | }) |
| | | needFly = false |
| | |
| | | import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial' |
| | | import lineImg from '@/assets/images/arrow-right-blue.png' |
| | | import uavImg from '@/assets/images/home/useUavHome/uavImg.png' |
| | | import { getCenterPoint } from '@/utils/cesium/mapUtil' |
| | | |
| | | const props = defineProps(['detailsData']) |
| | | |