项目级页面添加漫游、摄像头、定位设备、无人机、摄像头视频播放
This commit is contained in:
@ -6,11 +6,11 @@ VITE_APP_ENV = 'development'
|
||||
|
||||
# 开发环境
|
||||
|
||||
VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||
# 李陈杰 209
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||
# 曾涛
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
VITE_APP_BASE_API = 'http://192.168.110.180:8899'
|
||||
# 罗成
|
||||
# VITE_APP_BASE_API = 'http://192.168.110.188:8899'
|
||||
# 朱银
|
||||
|
1
public/vite.svg
Normal file
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
@ -123,6 +123,8 @@ function addPre() {
|
||||
|
||||
// 视频播放
|
||||
function videoPlay(obj: any) {
|
||||
console.log('objobjobj',obj);
|
||||
|
||||
getAccessToken().then((res: any) => {
|
||||
if (res.code == 200 && obj.deviceSerial) {
|
||||
flvPlayer.value = new EZUIKit.EZUIKitPlayer({
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="centerPage">
|
||||
<div class="topPage">
|
||||
<newMap></newMap>
|
||||
<newMap :isHide="isHide"></newMap>
|
||||
</div>
|
||||
<div class="endPage" :class="{ 'slide-out-down': isHide }">
|
||||
<Title title="AI安全巡检">
|
||||
@ -16,7 +16,7 @@
|
||||
<div class="swiper_content" ref="swiperContent">
|
||||
<div class="swiper_item" v-for="(item, i) in inspectionList" :key="i">
|
||||
<img :src="item.picture" alt="安全巡检" class="swiper_img">
|
||||
<div class="swiper_date">{{ item.createTime.slice(5) }}</div>
|
||||
<!-- <div class="swiper_date">{{ item.createTime.slice(5) }}</div> -->
|
||||
<div class="swiper_tip">{{ item.label }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,22 @@
|
||||
<script setup>
|
||||
import { onMounted, ref, onUnmounted } from 'vue';
|
||||
import { onMounted, ref, onUnmounted,defineProps} from 'vue';
|
||||
import CesiumImageLabelEntity from '../js/CesiumImageLabelEntity.js';
|
||||
import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js';
|
||||
import { setSelect, getSelectList, getGps } from '@/api/projectScreen/index.ts'
|
||||
import videoDialog from "./video.vue"
|
||||
const defaultExpandedKeys = [1, 2, 3] //默认展开第一级节点
|
||||
const defaultCheckedKeys = ref([]) //默认选中节点
|
||||
const data = ref([]);
|
||||
const deviceId = ref('');
|
||||
const videoDialogRef = ref(null);
|
||||
const props = defineProps({
|
||||
isHide:{
|
||||
type:Boolean,
|
||||
default:true,
|
||||
}
|
||||
})
|
||||
console.log('props', props);
|
||||
|
||||
const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
@ -58,15 +69,24 @@ function renderDevice(item) {
|
||||
lat: Number(item.lat),
|
||||
height: 0
|
||||
},
|
||||
imageWidth: 64,
|
||||
imageHeight: 64,
|
||||
name: item.label || item.id,
|
||||
imageUrl: "/assets/demo/avatar.png",
|
||||
onClick: entityClickHandler
|
||||
imageUrl: `/image/${item.type}.png`,
|
||||
onClick: (entity)=>{
|
||||
entityClickHandler(entity,item);
|
||||
}
|
||||
});
|
||||
window.deviceMap.set(item.id, imageEntity);
|
||||
}
|
||||
// 实体的点击事件
|
||||
function entityClickHandler(entity) {
|
||||
console.log('entity', entity);
|
||||
function entityClickHandler(entity,item) {
|
||||
console.log('entity', entity,item);
|
||||
if (item.type == 'camera') {
|
||||
deviceId.value = 'AE9470016';
|
||||
videoDialogRef.value.show();
|
||||
videoDialogRef.value.videoPlay(deviceId.value);
|
||||
}
|
||||
}
|
||||
// 初始化地球
|
||||
function initEarth() {
|
||||
@ -111,11 +131,6 @@ function loadTiltData(viewer) {
|
||||
// url:"http://58.17.134.85:7363/yjearth4.0/data/pak/e904acb32aaa8b872c64866ebaaaf5e2"
|
||||
url: import.meta.env.VITE_EARTH_URL + "/yjearth4.0/data/pak/4eb21d3fc02873092e75640e261544b3"
|
||||
});
|
||||
// var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
|
||||
// // url: 'http://58.17.134.85:7363/zm/api/v1/data/tileset/b15be28d053fcdd98308bed74c6108e6/tileset.json',
|
||||
// url:'http://58.17.134.85:7363/yjearth4.0/data/tileset/9c25649daa610a0cfb89e2cbea74bc55/tileset.json'
|
||||
// }));
|
||||
// console.log("加载倾斜数据:", tileset);
|
||||
}
|
||||
// 获取ArcGIS服务的URL
|
||||
function getArcGisUrlByType(type) {
|
||||
@ -218,17 +233,18 @@ onUnmounted(() => {
|
||||
<template>
|
||||
<div class="earth-container-big">
|
||||
<div class="earth" id="earth"></div>
|
||||
<div class="left">
|
||||
<div v-show="isHide" class="left">
|
||||
<div style="width: 100%;height: 100%;">
|
||||
<el-button type="primary" @click="startRoaming">开始漫游</el-button>
|
||||
<el-button type="primary" @click="stopRoaming">停止漫游</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div v-show="isHide" class="right">
|
||||
<el-tree show-checkbox :data="data" :props="defaultProps" node-key="id" :expand-on-click-node="false"
|
||||
:check-on-click-node="false" :check-on-click-leaf="false" :default-expanded-keys="defaultExpandedKeys"
|
||||
:default-checked-keys="defaultCheckedKeys" @check="handleCheck" @node-click="handleNodeClick" />
|
||||
</div>
|
||||
<videoDialog :data="deviceId" ref="videoDialogRef"></videoDialog>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
@ -255,7 +271,7 @@ onUnmounted(() => {
|
||||
.right,
|
||||
.left {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
width: 400px;
|
||||
height: 100%;
|
||||
transform: translateY(-50%);
|
||||
background-color: #00000052;
|
||||
|
109
src/views/projectLarge/ProjectScreen/components/video.vue
Normal file
109
src/views/projectLarge/ProjectScreen/components/video.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" title="摄像头直播" :width="dialogWidth" :height="dialogHeight" :before-close="handleClose"
|
||||
destroy-on-close>
|
||||
<div class="video-container-entity" id="video-container-entity" style="width: 100%; height: 600px"></div>
|
||||
<!-- <template #footer>
|
||||
<el-button type="primary" @click="handlesubmit">确定</el-button>
|
||||
<el-button type="danger" @click="handleClose">关闭</el-button>
|
||||
</template> -->
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, defineEmits, defineProps,onUnmounted } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getAccessToken } from '@/api/other/ys7Device';
|
||||
import EZUIKit from 'ezuikit-js';
|
||||
const emit = defineEmits(['send-data', 'close']);
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
}
|
||||
});
|
||||
// 弹窗控制变量
|
||||
const visible = ref(false);
|
||||
const dialogWidth = ref('950px');
|
||||
const dialogHeight = ref('90%');
|
||||
let loading = ref(true);
|
||||
const flvPlayer = ref(null);
|
||||
const show = () => {
|
||||
visible.value = true;
|
||||
}
|
||||
// 关闭弹窗
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
// 处理数据传递
|
||||
const handlesubmit = () => {
|
||||
handleClose();
|
||||
};
|
||||
// 视频播放
|
||||
function videoPlay(deviceSerial) {
|
||||
getAccessToken().then((res) => {
|
||||
if (res.code == 200 && deviceSerial) {
|
||||
flvPlayer.value = new EZUIKit.EZUIKitPlayer({
|
||||
audio: '0',
|
||||
id: 'video-container-entity',
|
||||
accessToken: res.data,
|
||||
url: `ezopen://open.ys7.com/${deviceSerial}/1.hd.live`,
|
||||
template: 'pcLive',
|
||||
width: 870,
|
||||
height: 600,
|
||||
plugin: ['talk'],
|
||||
handleError: function (err) {
|
||||
console.log(err);
|
||||
if (err?.data?.ret === 20020) {
|
||||
// 20020 是并发连接限制的错误码
|
||||
ElMessage.error('当前观看人数已达上限,请稍后再试');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 组件挂载时设置容器ID
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
|
||||
// 暴露显示方法给父组件
|
||||
defineExpose({
|
||||
show,
|
||||
videoPlay
|
||||
});
|
||||
|
||||
//
|
||||
onUnmounted(() => {
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.earth-container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 10px;
|
||||
height: calc(100% - 100px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.el-dialog) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 90vh;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__content) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
@ -53,8 +53,12 @@ export default class CesiumImageLabelEntity {
|
||||
// 创建实体
|
||||
this.entity = this.createEntity();
|
||||
|
||||
// 初始化点击事件监听
|
||||
this.initClickHandler();
|
||||
// 为实体添加标识,方便后续判断
|
||||
this.entity._isImageLabelEntity = true;
|
||||
this.entity._imageLabelInstance = this;
|
||||
|
||||
// 初始化全局点击事件(确保只注册一次)
|
||||
this.initGlobalClickHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,7 +71,7 @@ export default class CesiumImageLabelEntity {
|
||||
position: Cesium.Cartesian3.fromDegrees(
|
||||
this.options.position.lng,
|
||||
this.options.position.lat,
|
||||
this.options.position.alt
|
||||
this.options.position.height || 0 // 修复:使用height而非alt
|
||||
),
|
||||
show: this.options.show,
|
||||
|
||||
@ -79,8 +83,7 @@ export default class CesiumImageLabelEntity {
|
||||
color: this.options.imageColor,
|
||||
horizontalOrigin: this.options.horizontalOrigin,
|
||||
verticalOrigin: this.options.verticalOrigin,
|
||||
// 允许实体被选中
|
||||
pickable: true
|
||||
pickable: true // 确保可拾取
|
||||
},
|
||||
|
||||
// 名称标签属性
|
||||
@ -91,12 +94,10 @@ export default class CesiumImageLabelEntity {
|
||||
horizontalOrigin: this.options.horizontalOrigin,
|
||||
verticalOrigin: Cesium.VerticalOrigin.TOP,
|
||||
pixelOffset: new Cesium.Cartesian2(0, this.options.labelOffsetY),
|
||||
// 添加背景
|
||||
backgroundColor: new Cesium.Color(0, 0, 0, 0),
|
||||
backgroundColor: new Cesium.Color(0, 0, 0, 0.5), // 修复:半透明背景更易点击
|
||||
backgroundPadding: new Cesium.Cartesian2(5, 5),
|
||||
showBackground: true,
|
||||
// 允许标签被选中
|
||||
pickable: true
|
||||
pickable: true // 确保可拾取
|
||||
}
|
||||
});
|
||||
|
||||
@ -107,29 +108,33 @@ export default class CesiumImageLabelEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化点击事件处理器
|
||||
* 初始化全局点击事件处理器(只注册一次)
|
||||
*/
|
||||
initClickHandler() {
|
||||
// 存储当前实例的引用,方便在回调中使用
|
||||
const self = this;
|
||||
initGlobalClickHandler() {
|
||||
// 检查是否已注册全局事件,避免重复注册
|
||||
if (!this.viewer._imageLabelGlobalClickHandler) {
|
||||
const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
|
||||
|
||||
// 注册左击事件
|
||||
this.viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
|
||||
// 检测是否点击了当前实体
|
||||
const pickedObject = self.viewer.scene.pick(movement.position);
|
||||
handler.setInputAction((movement) => {
|
||||
const pickedObject = this.viewer.scene.pick(movement.position);
|
||||
|
||||
// 检查是否点击了当前实体或其实体的子组件(billboard、label等)
|
||||
if (Cesium.defined(pickedObject) &&
|
||||
(pickedObject.id === self.entity ||
|
||||
pickedObject.id === self.entity.billboard ||
|
||||
pickedObject.id === self.entity.label)) {
|
||||
|
||||
// 如果设置了点击回调,则执行
|
||||
if (self.onClickCallback && typeof self.onClickCallback === 'function') {
|
||||
self.onClickCallback(self.entity, movement.position);
|
||||
// 判断是否点击了我们创建的图片标签实体
|
||||
if (Cesium.defined(pickedObject) &&
|
||||
Cesium.defined(pickedObject.id) &&
|
||||
pickedObject.id._isImageLabelEntity) {
|
||||
// 调用对应实例的回调函数
|
||||
if (pickedObject.id._imageLabelInstance.onClickCallback) {
|
||||
pickedObject.id._imageLabelInstance.onClickCallback(
|
||||
pickedObject.id,
|
||||
movement.position
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
|
||||
// 存储全局事件处理器引用,避免重复创建
|
||||
this.viewer._imageLabelGlobalClickHandler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user