This commit is contained in:
ljx
2025-09-12 22:01:26 +08:00
parent 6bc9ed7054
commit 8316636c68
8 changed files with 426 additions and 381 deletions

View File

@ -5,7 +5,7 @@ import { AxiosPromise } from 'axios';
export const getScreenWeather = (projectId: number | string) => { export const getScreenWeather = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/weather/' + projectId, url: '/project/big/screen/weather/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -13,7 +13,7 @@ export const getScreenWeather = (projectId: number | string) => {
export const getScreenSafetyDay = (projectId: number | string) => { export const getScreenSafetyDay = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/safetyDay/' + projectId, url: '/project/big/screen/safetyDay/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -21,7 +21,7 @@ export const getScreenSafetyDay = (projectId: number | string) => {
export const getScreenNews = (projectId: number | string) => { export const getScreenNews = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/news/' + projectId, url: '/project/big/screen/news/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -29,7 +29,7 @@ export const getScreenNews = (projectId: number | string) => {
export const getScreenLand = (projectId: number | string) => { export const getScreenLand = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/' + projectId, url: '/project/big/screen/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -37,7 +37,7 @@ export const getScreenLand = (projectId: number | string) => {
export const getScreenImgProcess = (projectId: number | string) => { export const getScreenImgProcess = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/imageProgress/' + projectId, url: '/project/big/screen/imageProgress/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -45,15 +45,18 @@ export const getScreenImgProcess = (projectId: number | string) => {
export const getScreenPeople = (projectId: number | string) => { export const getScreenPeople = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/people/' + projectId, url: '/project/big/screen/people/' + projectId,
method: 'get', method: 'get'
}); });
}; };
// 查询项目AI安全巡检 // 查询项目AI安全巡检
export const getScreenSafetyInspection = (projectId: number | string) => { export const getScreenSafetyInspection = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/safetyInspection/' + projectId, url: '/project/big/screen/safetyInspection/',
method: 'get', method: 'get',
params: {
projectId
}
}); });
}; };
@ -61,7 +64,7 @@ export const getScreenSafetyInspection = (projectId: number | string) => {
export const getScreenGeneralize = (projectId: number | string) => { export const getScreenGeneralize = (projectId: number | string) => {
return request({ return request({
url: '/project/big/screen/generalize/' + projectId, url: '/project/big/screen/generalize/' + projectId,
method: 'get', method: 'get'
}); });
}; };
@ -76,7 +79,7 @@ export const getGps = (projectId) => {
export const getSelectList = (params) => { export const getSelectList = (params) => {
return request({ return request({
url: '/project/big/screen/getList', url: '/project/big/screen/getList',
method: 'get', method: 'get',
params params
}); });
}; };
@ -93,7 +96,7 @@ export const setSelect = (data) => {
export const getModelList = (params) => { export const getModelList = (params) => {
return request({ return request({
url: '/yjearth4.0/api/v1/source/list', url: '/yjearth4.0/api/v1/source/list',
method: 'get', method: 'get',
params params
}); });
}; };

View File

@ -53,6 +53,8 @@ const router = useRouter();
const getProjectGisData = async () => { const getProjectGisData = async () => {
try { try {
const response = await projectGis(); const response = await projectGis();
console.log(response, 111111111111);
if (response.code === 200) { if (response.code === 200) {
// 过滤掉没有经纬度的项目 // 过滤掉没有经纬度的项目
projectData.value = response.data.filter((item: any) => item.lng !== null && item.lat !== null && item.lng !== '' && item.lat !== ''); projectData.value = response.data.filter((item: any) => item.lng !== null && item.lat !== null && item.lng !== '' && item.lat !== '');
@ -108,6 +110,7 @@ const initEcharts = () => {
// 从接口数据生成散点数据 // 从接口数据生成散点数据
const scatterData = projectData.value.map((item) => ({ const scatterData = projectData.value.map((item) => ({
name: item.projectName, name: item.projectName,
id: item.id,
value: [parseFloat(item.lng), parseFloat(item.lat)], // 转换为数值类型 value: [parseFloat(item.lng), parseFloat(item.lat)], // 转换为数值类型
shortName: item.shortName, shortName: item.shortName,
projectSite: item.projectSite, projectSite: item.projectSite,
@ -200,15 +203,18 @@ const initEcharts = () => {
myChart.setOption(option); myChart.setOption(option);
// 添加点击事件监听 - 这是关键修改部分 // 添加点击事件监听 - 这是关键修改部分
myChart.on('click', function (params: any) { myChart.on('click', function (params: any) {
console.log(params, 111111);
// 检查点击的是散点图系列 // 检查点击的是散点图系列
if (params.componentType === 'series' && params.seriesType === 'scatter') { if (params.componentType === 'series' && params.seriesType === 'scatter') {
// 跳转到项目详情页 // 跳转到项目详情页
navigateToProjectDetail();
navigateToProjectDetail(params.data);
} }
}); });
}; };
const navigateToProjectDetail = () => { const navigateToProjectDetail = (data) => {
window.open('http://xny.yj-3d.com:7788/ProjectScreen', '_blank'); window.open('http://localhost:7788/ProjectScreen?projectId=' + data.id + '&projectName=' + data.name, '_blank');
//xny.yj-3d.com
}; };
const risk_level_type1 = ref([]); const risk_level_type1 = ref([]);
const safety_inspection_type1 = ref([]); const safety_inspection_type1 = ref([]);

View File

@ -5,7 +5,7 @@
</div> </div>
<div class="endPage" :class="{ 'slide-out-down': isHide }"> <div class="endPage" :class="{ 'slide-out-down': isHide }">
<Title title="AI安全巡检"> <Title title="AI安全巡检">
<img src="@/assets/projectLarge/robot.svg" alt="" height="20px" width="20px"> <img src="@/assets/projectLarge/robot.svg" alt="" height="20px" width="20px" />
</Title> </Title>
<div class="swiper" v-if="inspectionList.length"> <div class="swiper" v-if="inspectionList.length">
<div class="arrow" :class="{ 'canUse': canLeft }" @click="swiperClick('left')"> <div class="arrow" :class="{ 'canUse': canLeft }" @click="swiperClick('left')">
@ -15,7 +15,7 @@
</div> </div>
<div class="swiper_content" ref="swiperContent"> <div class="swiper_content" ref="swiperContent">
<div class="swiper_item" v-for="(item, i) in inspectionList" :key="i"> <div class="swiper_item" v-for="(item, i) in inspectionList" :key="i">
<img :src="item.picture" alt="安全巡检" class="swiper_img"> <img :src="item.picture" alt="安全巡检" class="swiper_img" />
<div class="swiper_date">{{ item.createTime.slice(5, 16) }}</div> <div class="swiper_date">{{ item.createTime.slice(5, 16) }}</div>
<div class="swiper_tip">{{ item.label || '未佩戴安全帽' }}</div> <div class="swiper_tip">{{ item.label || '未佩戴安全帽' }}</div>
</div> </div>
@ -31,14 +31,15 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, toRefs, getCurrentInstance } from "vue" import { ref, onMounted, toRefs, getCurrentInstance } from 'vue';
import Title from './title.vue' import Title from './title.vue';
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue' import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue';
import { getScreenSafetyInspection } from '@/api/projectScreen' import { getScreenSafetyInspection } from '@/api/projectScreen';
import newMap from "./newmap.vue" import newMap from './newmap.vue';
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { violation_level_type } = toRefs(proxy?.useDict('violation_level_type')); const { violation_level_type } = toRefs(proxy?.useDict('violation_level_type'));
const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
const props = defineProps({ const props = defineProps({
isHide: { isHide: {
type: Boolean, type: Boolean,
@ -46,88 +47,91 @@ const props = defineProps({
}, },
projectId: { projectId: {
type: String, type: String,
default: "" default: ''
} }
}) });
const inspectionList = ref([{ const inspectionList = ref([
id: "", {
label: "", id: '',
picture: "", label: '',
createTime: "" picture: '',
}]) createTime: ''
const swiperContent = ref() }
const swiperItemWidth = ref(100) ]);
const canLeft = ref(false) const swiperContent = ref();
const canRight = ref(true) const swiperItemWidth = ref(100);
const canLeft = ref(false);
const canRight = ref(true);
const swiperClick = (direction) => { const swiperClick = (direction) => {
if (!swiperContent.value) return if (!swiperContent.value) return;
if (direction === 'right') { if (direction === 'right') {
if (swiperContent.value.scrollLeft >= swiperContent.value.scrollWidth - swiperContent.value.clientWidth) { if (swiperContent.value.scrollLeft >= swiperContent.value.scrollWidth - swiperContent.value.clientWidth) {
canRight.value = false canRight.value = false;
canLeft.value = true canLeft.value = true;
return return;
} }
swiperContent.value.scrollLeft += swiperItemWidth.value swiperContent.value.scrollLeft += swiperItemWidth.value;
} else { } else {
if (swiperContent.value.scrollLeft <= 0) { if (swiperContent.value.scrollLeft <= 0) {
canLeft.value = false canLeft.value = false;
canRight.value = true canRight.value = true;
return return;
} }
swiperContent.value.scrollLeft -= swiperItemWidth.value swiperContent.value.scrollLeft -= swiperItemWidth.value;
} }
// 更新箭头状态 // 更新箭头状态
canLeft.value = swiperContent.value.scrollLeft > 0 canLeft.value = swiperContent.value.scrollLeft > 0;
canRight.value = swiperContent.value.scrollLeft < swiperContent.value.scrollWidth - swiperContent.value.clientWidth canRight.value = swiperContent.value.scrollLeft < swiperContent.value.scrollWidth - swiperContent.value.clientWidth;
} };
const getInspectionList = async () => { const getInspectionList = () => {
const res = await getScreenSafetyInspection(props.projectId) getScreenSafetyInspection(projectIdTwo).then((res) => {
const { code, data } = res const { code, data } = res;
if (code === 200) { if (code === 200) {
console.log(violation_level_type.value) console.log(violation_level_type.value);
data.map(item => { data.map((item) => {
item.label = violation_level_type.value.find((i) => i.value === item.violationType)?.label item.label = violation_level_type.value.find((i) => i.value === item.violationType)?.label;
}) });
inspectionList.value = data inspectionList.value = data;
} }
} });
};
// 创建地球 // 创建地球
const createEarth = () => { const createEarth = () => {
window.YJ.on({ window.YJ.on({
ws: true, ws: true
// host: getIP(), //资源所在服务器地址 // host: getIP(), //资源所在服务器地址
// username: this.loginForm.username, //用户名 可以不登录(不填写用户名),不登录时无法加载服务端的数据 // username: this.loginForm.username, //用户名 可以不登录(不填写用户名),不登录时无法加载服务端的数据
// password: md5pass, //密码 生成方式md5(用户名_密码) // password: md5pass, //密码 生成方式md5(用户名_密码)
}).then((res) => { }).then((res) => {
let earth = new YJ.YJEarth("earth"); let earth = new YJ.YJEarth('earth');
window.Earth1 = earth; window.Earth1 = earth;
YJ.Global.openRightClick(window.Earth1); YJ.Global.openRightClick(window.Earth1);
YJ.Global.openLeftClick(window.Earth1); YJ.Global.openLeftClick(window.Earth1);
let view = { let view = {
"position": { 'position': {
"lng": 102.03643298211526, 'lng': 102.03643298211526,
"lat": 34.393586474501, 'lat': 34.393586474501,
"alt": 11298179.51993155 'alt': 11298179.51993155
}, },
"orientation": { 'orientation': {
"heading": 360, 'heading': 360,
"pitch": -89.94481747201486, 'pitch': -89.94481747201486,
"roll": 0 'roll': 0
} }
} };
loadBaseMap(earth.viewer) loadBaseMap(earth.viewer);
YJ.Global.CesiumContainer(window.Earth1, { YJ.Global.CesiumContainer(window.Earth1, {
compass: false, //罗盘 compass: false //罗盘
}); });
// YJ.Global.flyTo(earth, view); // YJ.Global.flyTo(earth, view);
// YJ.Global.setDefaultView(earth.viewer, view) // YJ.Global.setDefaultView(earth.viewer, view)
}) });
} };
// 加载底图 // 加载底图
const loadBaseMap = (viewer) => { const loadBaseMap = (viewer) => {
// 创建瓦片提供器 // 创建瓦片提供器
@ -146,14 +150,14 @@ const loadBaseMap = (viewer) => {
// 添加图层到视图 // 添加图层到视图
const layer = viewer.imageryLayers.addImageryProvider(imageryProvider); const layer = viewer.imageryLayers.addImageryProvider(imageryProvider);
} };
onMounted(() => { onMounted(() => {
getInspectionList() getInspectionList();
if (swiperContent.value && swiperContent.value.children.length > 0) { if (swiperContent.value && swiperContent.value.children.length > 0) {
swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20 swiperItemWidth.value = swiperContent.value.children[0].clientWidth + 20;
} }
}) });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -11,7 +11,7 @@
</div> </div>
</div> </div>
<div class="title"> <div class="title">
<div>{{ currentProjectName }}</div> <div>{{ projectName ? projectName : currentProjectName }}</div>
<div>施工现场数智化管理</div> <div>施工现场数智化管理</div>
</div> </div>
<div class="header_right"> <div class="header_right">
@ -19,8 +19,12 @@
<!-- 左侧天气图标 + 日期文字 --> <!-- 左侧天气图标 + 日期文字 -->
<div class="left-section"> <div class="left-section">
<div class="weather-list" @mouseenter="requestPause" @mouseleave="resumeScroll"> <div class="weather-list" @mouseenter="requestPause" @mouseleave="resumeScroll">
<div v-for="(item, i) in weatherList" :key="i" class="weather-item" <div
:style="{ transform: `translateY(-${offsetY}px)`, transition: transition }"> v-for="(item, i) in weatherList"
:key="i"
class="weather-item"
:style="{ transform: `translateY(-${offsetY}px)`, transition: transition }"
>
<img :src="`/assets/demo/${item.icon}.png`" alt="" /> <img :src="`/assets/demo/${item.icon}.png`" alt="" />
<div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div> <div>{{ item.weather }}{{ item.tempMin }}°/{{ item.tempMax }}°</div>
<div>{{ item.week }}({{ item.date }})</div> <div>{{ item.week }}({{ item.date }})</div>
@ -60,7 +64,9 @@
import { ref, onMounted, onUnmounted } from 'vue'; import { ref, onMounted, onUnmounted } from 'vue';
import { getScreenSafetyDay, getScreenWeather } from '@/api/projectScreen'; import { getScreenSafetyDay, getScreenWeather } from '@/api/projectScreen';
import { useUserStoreHook } from '@/store/modules/user'; import { useUserStoreHook } from '@/store/modules/user';
const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
const projectName = urlParams.get('projectName');
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
const currentProjectName = computed(() => userStore.selectedProject?.name); const currentProjectName = computed(() => userStore.selectedProject?.name);
@ -81,6 +87,10 @@ const props = defineProps({
isFull: { isFull: {
type: Boolean, type: Boolean,
default: false default: false
},
projectName: {
type: String,
default: ''
} }
}); });
@ -230,13 +240,13 @@ onUnmounted(() => {
text-align: center; text-align: center;
} }
.title>div:first-child { .title > div:first-child {
/* 第一个子元素的样式 */ /* 第一个子元素的样式 */
font-size: 38px; font-size: 38px;
letter-spacing: 0.1em; letter-spacing: 0.1em;
} }
.title>div:last-child { .title > div:last-child {
/* 最后一个子元素的样式 */ /* 最后一个子元素的样式 */
font-size: 26px; font-size: 26px;
} }
@ -269,7 +279,7 @@ onUnmounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
&>div:last-child { & > div:last-child {
margin-left: 10px; margin-left: 10px;
} }

View File

@ -90,7 +90,8 @@ import Title from './title.vue';
import { getScreenNews, getScreenPeople } from '@/api/projectScreen/index'; import { getScreenNews, getScreenPeople } from '@/api/projectScreen/index';
import { mapOption } from './optionList'; import { mapOption } from './optionList';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
const props = defineProps({ const props = defineProps({
projectId: { projectId: {
type: String, type: String,
@ -128,7 +129,7 @@ const showNewsDetail = (item: any) => {
* 获取项目人员出勤数据 * 获取项目人员出勤数据
*/ */
const getPeopleData = async () => { const getPeopleData = async () => {
const res = await getScreenPeople(props.projectId); const res = await getScreenPeople(projectIdTwo);
const { data, code } = res; const { data, code } = res;
if (code === 200) { if (code === 200) {
console.log(data); console.log(data);
@ -143,7 +144,7 @@ const getPeopleData = async () => {
* 获取项目新闻数据 * 获取项目新闻数据
*/ */
const getNewsData = async () => { const getNewsData = async () => {
const res = await getScreenNews(props.projectId); const res = await getScreenNews(projectIdTwo);
const { data, code } = res; const { data, code } = res;
if (code === 200) { if (code === 200) {
news.value = data; news.value = data;

View File

@ -2,42 +2,46 @@
import { onMounted, ref, onUnmounted, defineProps } from 'vue'; import { onMounted, ref, onUnmounted, defineProps } from 'vue';
import CesiumImageLabelEntity from '../js/CesiumImageLabelEntity.js'; import CesiumImageLabelEntity from '../js/CesiumImageLabelEntity.js';
import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js'; import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js';
import { setSelect, getSelectList, getGps, getModelList } from '@/api/projectScreen/index.ts' import { setSelect, getSelectList, getGps, getModelList } from '@/api/projectScreen/index.ts';
import videoDialog from "./video.vue" import videoDialog from './video.vue';
import { getToken } from '@/utils/auth'; import { getToken } from '@/utils/auth';
import axios from 'axios'; import axios from 'axios';
import md5 from 'js-md5'; import md5 from 'js-md5';
const defaultExpandedKeys = [1, 2, 3] //默认展开第一级节点 const defaultExpandedKeys = [1, 2, 3]; //默认展开第一级节点
const defaultCheckedKeys = ref([]) //默认选中节点 const defaultCheckedKeys = ref([]); //默认选中节点
const data = ref([]); const data = ref([]);
const deviceId = ref(''); const deviceId = ref('');
const videoDialogRef = ref(null); const videoDialogRef = ref(null);
const token = getToken(); const token = getToken();
let ws = new ReconnectingWebSocket(import.meta.env.VITE_APP_BASE_WS_API + '?Authorization=' + token + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID + '&projectId=' + '1897160897167638529'); const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
let ws = new ReconnectingWebSocket(
import.meta.env.VITE_APP_BASE_WS_API + '?Authorization=' + token + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID + '&projectId=' + projectIdTwo
);
// 连接ws // 连接ws
const connectWs = () => { const connectWs = () => {
ws.onopen = (e) => { ws.onopen = (e) => {
// let message ={ // let message ={
// projectId:'1897160897167638529', // projectId:'1897160897167638529',
// } // }
// ws.send(JSON.stringify(message)); // ws.send(JSON.stringify(message));
ws.onmessage = (e) => { ws.onmessage = (e) => {
console.log('ws', e); console.log('ws', e);
};
}; };
} };
};
const props = defineProps({ const props = defineProps({
isHide: { isHide: {
type: Boolean, type: Boolean,
default: true, default: true
} }
}) });
console.log('props', props); console.log('props', props);
const defaultProps = { const defaultProps = {
children: 'children', children: 'children',
label: 'label', label: 'label'
} };
let entityManager = null; let entityManager = null;
window.deviceMap = new Map(); window.deviceMap = new Map();
window.ModelList = new Map(); window.ModelList = new Map();
@ -48,299 +52,311 @@ let modelList = ref([]);
let roamingController = null; let roamingController = null;
// 获取模型列表 // 获取模型列表
async function getModelListData() { async function getModelListData() {
let res = await axios.post(import.meta.env.VITE_APP_BASE_EARTH_API + '/yjearth4.0/api/v1/user/sign-in', let res = await axios.post(import.meta.env.VITE_APP_BASE_EARTH_API + '/yjearth4.0/api/v1/user/sign-in', {
{ "username": "admin", "password": "3598f66fbc93c0d5abd2dabab9de74cc" } 'username': 'admin',
) 'password': '3598f66fbc93c0d5abd2dabab9de74cc'
console.log('res', res.data); });
if (res.data.code == 0) { console.log('res', res.data);
let toekn = res.data.data.token; if (res.data.code == 0) {
console.log('toekn', toekn); let toekn = res.data.data.token;
let res1 = await axios({ console.log('toekn', toekn);
url: import.meta.env.VITE_APP_BASE_EARTH_API + '/yjearth4.0/api/v1/source/list', let res1 = await axios({
method: 'post', url: import.meta.env.VITE_APP_BASE_EARTH_API + '/yjearth4.0/api/v1/source/list',
data: { method: 'post',
data: { "page": 1, "page_size": 10 }, data: {
}, data: { 'page': 1, 'page_size': 10 }
headers: { },
'token': toekn headers: {
} 'token': toekn
}) }
if (res1.data.code == 0) { });
modelList.value = res1.data.data.list; if (res1.data.code == 0) {
} modelList.value = res1.data.data.list;
} }
}
} }
// 获取GPS数据 // 获取GPS数据
function getGpsData() { function getGpsData() {
getGps('1897160897167638529').then(res => { getGps(projectIdTwo).then((res) => {
console.log('res', res); console.log('res', res);
if (res.code === 200) { if (res.code === 200) {
data.value = res.data; data.value = res.data;
if (res.data.length > 0) { if (res.data.length > 0) {
res.data.forEach(element => { res.data.forEach((element) => {
list.value = [...list.value, ...element.children] list.value = [...list.value, ...element.children];
}); });
} }
} }
}) });
} }
// 设置选中节点 // 设置选中节点
function setCheckedNode(idList) { function setCheckedNode(idList) {
let obj = { let obj = {
projectId: '1897160897167638529', projectId: projectIdTwo,
idList idList
} };
setSelect(obj).then(res => { setSelect(obj).then((res) => {
console.log('res', res); console.log('res', res);
}) });
} }
// 获取选中节点 // 获取选中节点
function getCheckedNode() { function getCheckedNode() {
getSelectList({ getSelectList({
projectId: '1897160897167638529' projectId: projectIdTwo
}).then(res => { }).then((res) => {
if (res.code == 200) { if (res.code == 200) {
defaultCheckedKeys.value = res.data || [] defaultCheckedKeys.value = res.data || [];
} }
}) });
} }
// 渲染无人机、摄像头、定位设备 // 渲染无人机、摄像头、定位设备
function renderDevice(item) { function renderDevice(item) {
const imageEntity = new CesiumImageLabelEntity(Earth1.viewer, { const imageEntity = new CesiumImageLabelEntity(Earth1.viewer, {
id: item.id, id: item.id,
position: { position: {
lng: Number(item.lng), lng: Number(item.lng),
lat: Number(item.lat), lat: Number(item.lat),
height: 0 height: 0
}, },
imageWidth: 64, imageWidth: 64,
imageHeight: 64, imageHeight: 64,
name: item.label || item.id, name: item.label || item.id,
imageUrl: `/image/${item.type}.png`, imageUrl: `/image/${item.type}.png`,
onClick: (entity) => { onClick: (entity) => {
entityClickHandler(entity, item); entityClickHandler(entity, item);
} }
}); });
window.deviceMap.set(item.id, imageEntity); window.deviceMap.set(item.id, imageEntity);
} }
// 实体的点击事件 // 实体的点击事件
function entityClickHandler(entity, item) { function entityClickHandler(entity, item) {
console.log('entity', entity, item); console.log('entity', entity, item);
if (item.type == 'camera') { if (item.type == 'camera') {
deviceId.value = 'AE9470016'; deviceId.value = 'AE9470016';
videoDialogRef.value.show(); videoDialogRef.value.show();
videoDialogRef.value.videoPlay(deviceId.value); videoDialogRef.value.videoPlay(deviceId.value);
} }
} }
// 初始化地球 // 初始化地球
async function initEarth() { async function initEarth() {
let earth = new YJ.YJEarth('earth');
let earth = new YJ.YJEarth("earth"); window.Earth1 = earth;
// 加载底图
window.Earth1 = earth; // earth.viewer.terrainProvider = Cesium.createWorldTerrain();
// 加载底图 // Earth1.viewer
// earth.viewer.terrainProvider = Cesium.createWorldTerrain(); addArcgisLayer(Earth1.viewer, 'img_w');
// Earth1.viewer // 添加倾斜数据
addArcgisLayer(Earth1.viewer, 'img_w') // 获取中心点
// 添加倾斜数据 YJ.Global.CesiumContainer(window.Earth1, {
// 获取中心点 compass: false, //罗盘
YJ.Global.CesiumContainer(window.Earth1, { legend: false //图例
compass: false,//罗盘 });
legend: false, //图 // 创建实体管理器实
}); list.value.forEach((item) => {
// 创建实体管理器实例 if (defaultCheckedKeys.value.includes(item.id)) {
list.value.forEach(item => { console.log('defaultCheckedKeys', item.id);
if (defaultCheckedKeys.value.includes(item.id)) { renderDevice(item);
console.log("defaultCheckedKeys", item.id); }
renderDevice(item) });
} roamingController = new CesiumFlyToRoamingController(window.Earth1.viewer, {
}); duration: 5, // 每个点之间飞行5秒
roamingController = new CesiumFlyToRoamingController(window.Earth1.viewer, { pitch: -89 // 20度俯角
duration: 5, // 每个点之间飞行5秒 });
pitch: -89 // 20度俯角 window.roamingController = roamingController;
});
window.roamingController = roamingController;
} }
async function loadTiltData(item) { async function loadTiltData(item) {
let tileset = new YJ.Obj.Tileset(window.Earth1, { id: item.source_id }); let tileset = new YJ.Obj.Tileset(window.Earth1, { id: item.source_id });
ModelList.set(item.source_id, tileset); ModelList.set(item.source_id, tileset);
await tileset.on(); await tileset.on();
tileset.flyTo(); tileset.flyTo();
} }
// 获取ArcGIS服务的URL // 获取ArcGIS服务的URL
function getArcGisUrlByType(type) { function getArcGisUrlByType(type) {
switch (type) { switch (type) {
//影像 //影像
case "img_w": case 'img_w':
return "https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}"; return 'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}';
//电子 //电子
case "vec_w": case 'vec_w':
return "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"; return 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer';
//蓝色底图 //蓝色底图
case "vec_blue": case 'vec_blue':
return "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer"; return 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer';
//灰色底图 //灰色底图
case "vec_gray": case 'vec_gray':
return "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetGray/MapServer"; return 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetGray/MapServer';
//暖色底图 //暖色底图
case "vec_warm": case 'vec_warm':
return "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer"; return 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer';
} }
} }
// 添加ArcGIS图层 // 添加ArcGIS图层
function addArcgisLayer(viewer, type) { function addArcgisLayer(viewer, type) {
let url = getArcGisUrlByType(type) let url = getArcGisUrlByType(type);
const layerProvider = new Cesium.UrlTemplateImageryProvider({ const layerProvider = new Cesium.UrlTemplateImageryProvider({
url: url url: url
}); });
viewer.imageryLayers.addImageryProvider(layerProvider); viewer.imageryLayers.addImageryProvider(layerProvider);
} }
// 节点单击事件 // 节点单击事件
function handleNodeClick(data) { function handleNodeClick(data) {
console.log('data', data); console.log('data', data);
let entity = window.deviceMap.get(data.id); let entity = window.deviceMap.get(data.id);
if (entity) { if (entity) {
entity.flyTo(); entity.flyTo();
} }
} }
// 复选框选中事件 // 复选框选中事件
function handleCheck(checkedNodes, nodes) { function handleCheck(checkedNodes, nodes) {
console.log('check', checkedNodes, nodes); console.log('check', checkedNodes, nodes);
// 处理单个节点的通用函数 // 处理单个节点的通用函数
const handleNode = (node) => { const handleNode = (node) => {
if (!window.deviceMap.has(node.id)) { if (!window.deviceMap.has(node.id)) {
console.log("defaultCheckedKeys", node.id); console.log('defaultCheckedKeys', node.id);
renderDevice(node); renderDevice(node);
} else {
const device = window.deviceMap.get(node.id);
// 根据当前显示状态切换显示/隐藏
device[device.entity.show ? 'hide' : 'show']();
}
};
// 处理选中的节点(可能是单个节点或包含子节点的集合)
if (checkedNodes?.children?.length) {
console.log('children', checkedNodes.children);
checkedNodes.children.forEach(handleNode);
} else { } else {
handleNode(checkedNodes); const device = window.deviceMap.get(node.id);
// 根据当前显示状态切换显示/隐藏
device[device.entity.show ? 'hide' : 'show']();
} }
};
setCheckedNode(nodes.checkedKeys); // 处理选中的节点(可能是单个节点或包含子节点的集合)
if (checkedNodes?.children?.length) {
console.log('children', checkedNodes.children);
checkedNodes.children.forEach(handleNode);
} else {
handleNode(checkedNodes);
}
setCheckedNode(nodes.checkedKeys);
} }
// 开始漫游 // 开始漫游
function startRoaming() { function startRoaming() {
if (roamingController) { if (roamingController) {
roamingController.startPathRoaming([ roamingController.startPathRoaming(
Cesium.Cartesian3.fromDegrees(106.49556855602525, 29.534393226355515, 200), [
Cesium.Cartesian3.fromDegrees(106.49142431645038, 29.534472802500083, 200), Cesium.Cartesian3.fromDegrees(106.49556855602525, 29.534393226355515, 200),
Cesium.Cartesian3.fromDegrees(106.49142125177437, 29.541881138875755, 200) Cesium.Cartesian3.fromDegrees(106.49142431645038, 29.534472802500083, 200),
], 3, false); Cesium.Cartesian3.fromDegrees(106.49142125177437, 29.541881138875755, 200)
} else { ],
console.log('请先初始化地球'); 3,
} false
);
} else {
console.log('请先初始化地球');
}
} }
// 停止漫游 // 停止漫游
function stopRoaming() { function stopRoaming() {
if (roamingController) { if (roamingController) {
roamingController.stopRoaming(); roamingController.stopRoaming();
} else { } else {
console.log('请先初始化地球'); console.log('请先初始化地球');
} }
} }
onMounted(async () => { onMounted(async () => {
// 连接ws
// 连接ws connectWs();
connectWs(); // 获取选中节点
// 获取选中节点 getCheckedNode();
getCheckedNode(); // 获取GPS数据
// 获取GPS数据 getGpsData();
getGpsData(); await getModelListData();
await getModelListData(); await YJ.on({
await YJ.on({ username: 'admin',
username: 'admin', password: md5('admin_admin123'),
password: md5('admin_admin123'), host: 'http://192.168.110.2:8895/'
host: 'http://192.168.110.2:8895/' }).then((res) => {
}).then((res) => { initEarth();
initEarth(); modelList.value.forEach((item) => {
modelList.value.forEach(item => { loadTiltData(item);
loadTiltData(item)
})
}); });
});
}); });
onUnmounted(() => { onUnmounted(() => {
window.deviceMap.forEach((item) => { window.deviceMap.forEach((item) => {
item.destroy(); item.destroy();
}) });
window.deviceMap.clear(); window.deviceMap.clear();
window.roamingController.destroy(); window.roamingController.destroy();
window.Earth1.destroy(); window.Earth1.destroy();
}) });
</script> </script>
<template> <template>
<div class="earth-container-big"> <div class="earth-container-big">
<div class="earth" id="earth"></div> <div class="earth" id="earth"></div>
<!-- <div v-show="isHide" class="left"> <!-- <div v-show="isHide" class="left">
<div style="width: 100%;height: 100%;"> <div style="width: 100%;height: 100%;">
<el-button type="primary" @click="startRoaming">开始漫游</el-button> <el-button type="primary" @click="startRoaming">开始漫游</el-button>
<el-button type="primary" @click="stopRoaming">停止漫游</el-button> <el-button type="primary" @click="stopRoaming">停止漫游</el-button>
</div> </div>
</div> --> </div> -->
<div v-show="isHide" class="right"> <div v-show="isHide" class="right">
<el-tree show-checkbox :data="data" :props="defaultProps" node-key="id" :expand-on-click-node="false" <el-tree
:check-on-click-node="false" :check-on-click-leaf="false" :default-expanded-keys="defaultExpandedKeys" show-checkbox
:default-checked-keys="defaultCheckedKeys" @check="handleCheck" @node-click="handleNodeClick" /> :data="data"
</div> :props="defaultProps"
<videoDialog :data="deviceId" ref="videoDialogRef"></videoDialog> 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> </div>
<videoDialog :data="deviceId" ref="videoDialogRef"></videoDialog>
</div>
</template> </template>
<style lang="scss"> <style lang="scss">
.earth-container-big { .earth-container-big {
position: relative; position: relative;
width: 100%;
height: 100%;
.earth {
width: 100%; width: 100%;
height: 100%; height: 100%;
}
.earth { .right {
width: 100%; top: 50%;
height: 100%; right: 0;
} }
.right { .left {
top: 50%; top: 50%;
right: 0; left: 0;
} }
.left { .right,
top: 50%; .left {
left: 0; position: absolute;
} width: 400px;
height: 100%;
.right, transform: translateY(-50%);
.left { background-color: #00000052;
position: absolute; padding: 20px;
width: 400px; box-sizing: border-box;
height: 100%; z-index: 10;
transform: translateY(-50%);
background-color: #00000052; .el-tree {
padding: 20px; background-color: transparent;
box-sizing: border-box; --el-tree-node-hover-bg-color: transparent;
z-index: 10; --el-tree-text-color: #fff;
.el-tree { .el-text {
background-color: transparent; color: azure;
--el-tree-node-hover-bg-color: transparent; }
--el-tree-text-color: #fff;
.el-tree-node__content:hover {
.el-text { background-color: transparent;
color: azure; }
}
.el-tree-node__content:hover {
background-color: transparent;
}
}
} }
}
} }
</style> </style>

View File

@ -16,30 +16,31 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick } from "vue" import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import Title from './title.vue' import Title from './title.vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { pieOption, barOption } from './optionList'; import { pieOption, barOption } from './optionList';
import { getScreenLand, getScreenImgProcess, getScreenGeneralize } from '@/api/projectScreen'; import { getScreenLand, getScreenImgProcess, getScreenGeneralize } from '@/api/projectScreen';
const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
const props = defineProps({ const props = defineProps({
projectId: { projectId: {
type: String, type: String,
default: 0 default: 0
} }
}) });
const generalize = ref() const generalize = ref();
// 饼图相关 // 饼图相关
const pieChartRef = ref<HTMLDivElement | null>(null); const pieChartRef = ref<HTMLDivElement | null>(null);
let pieChart: any = null; let pieChart: any = null;
const totalPercent = ref(0) const totalPercent = ref(0);
// 折线图相关 // 折线图相关
const lineChartRef = ref<HTMLDivElement | null>(null); const lineChartRef = ref<HTMLDivElement | null>(null);
let lineChart: any = null; let lineChart: any = null;
// 土地数据 折线图 // 土地数据 折线图
const designAreaData = ref([]) const designAreaData = ref([]);
const transferAreaData = ref([]) const transferAreaData = ref([]);
// 饼图数据 // 饼图数据
let pieData = [ let pieData = [
{ label: 'areaPercentage', name: '场区', value: 0 }, { label: 'areaPercentage', name: '场区', value: 0 },
@ -47,8 +48,8 @@ let pieData = [
{ label: 'collectorLinePercentage', name: '集电线路', value: 0 }, { label: 'collectorLinePercentage', name: '集电线路', value: 0 },
{ label: 'exportLinePercentage', name: '送出线路', value: 0 }, { label: 'exportLinePercentage', name: '送出线路', value: 0 },
{ label: 'substationPercentage', name: '升压站', value: 0 }, { label: 'substationPercentage', name: '升压站', value: 0 },
{ label: 'boxTransformerPercentage', name: '箱变', value: 0 }, { label: 'boxTransformerPercentage', name: '箱变', value: 0 }
] ];
// 初始化饼图 // 初始化饼图
const initPieChart = () => { const initPieChart = () => {
@ -56,14 +57,14 @@ const initPieChart = () => {
console.error('未找到饼图容器元素'); console.error('未找到饼图容器元素');
return; return;
} }
pieOption.series.data = pieData pieOption.series.data = pieData;
pieOption.graphic[0].style.text = totalPercent.value + '%' pieOption.graphic[0].style.text = totalPercent.value + '%';
pieChart = echarts.init(pieChartRef.value, null, { pieChart = echarts.init(pieChartRef.value, null, {
renderer: 'canvas', renderer: 'canvas',
useDirtyRect: false useDirtyRect: false
}); });
pieChart.setOption(pieOption); pieChart.setOption(pieOption);
} };
// 初始化折线图 // 初始化折线图
const initLineChart = () => { const initLineChart = () => {
@ -71,55 +72,55 @@ const initLineChart = () => {
console.error('未找到折线图容器元素'); console.error('未找到折线图容器元素');
return; return;
} }
barOption.series[0].data = designAreaData.value barOption.series[0].data = designAreaData.value;
barOption.series[1].data = transferAreaData.value barOption.series[1].data = transferAreaData.value;
lineChart = echarts.init(lineChartRef.value, null, { lineChart = echarts.init(lineChartRef.value, null, {
renderer: 'canvas', renderer: 'canvas',
useDirtyRect: false useDirtyRect: false
}); });
lineChart.setOption(barOption); lineChart.setOption(barOption);
} };
/** /**
* 获取项目土地统计数据 * 获取项目土地统计数据
*/ */
const getScreenLandData = async () => { const getScreenLandData = async () => {
const res = await getScreenLand(props.projectId); const res = await getScreenLand(projectIdTwo);
const { data, code } = res const { data, code } = res;
if (code === 200) { if (code === 200) {
designAreaData.value = data.map((item: any) => Number(item.designArea)) designAreaData.value = data.map((item: any) => Number(item.designArea));
transferAreaData.value = data.map((item: any) => Number(item.transferArea)) transferAreaData.value = data.map((item: any) => Number(item.transferArea));
initLineChart(); initLineChart();
} }
} };
/** /**
* 获取项目形象进度数据 * 获取项目形象进度数据
*/ */
const getScreenImgProcessData = async () => { const getScreenImgProcessData = async () => {
const res = await getScreenImgProcess(props.projectId); const res = await getScreenImgProcess(projectIdTwo);
const { data, code } = res const { data, code } = res;
if (code === 200) { if (code === 200) {
totalPercent.value = data.totalPercentage totalPercent.value = data.totalPercentage;
pieData.forEach((item: any) => { pieData.forEach((item: any) => {
item.value = data[item.label] item.value = data[item.label];
}) });
pieData = pieData.filter((item: any) => item.value != '0.0') pieData = pieData.filter((item: any) => item.value != '0.0');
console.log(pieData) console.log(pieData);
initPieChart() initPieChart();
} }
} };
/** /**
* 获取项目概况数据 * 获取项目概况数据
*/ */
const getScreenGeneralizeData = async () => { const getScreenGeneralizeData = async () => {
const res = await getScreenGeneralize(props.projectId); const res = await getScreenGeneralize(projectIdTwo);
const { data, code, msg } = res const { data, code, msg } = res;
if (code === 200) { if (code === 200) {
generalize.value = msg generalize.value = msg;
} }
} };
// 响应窗口大小变化 // 响应窗口大小变化
const handleResize = () => { const handleResize = () => {
@ -129,9 +130,9 @@ const handleResize = () => {
// 组件挂载时初始化图表 // 组件挂载时初始化图表
onMounted(() => { onMounted(() => {
getScreenLandData() getScreenLandData();
getScreenImgProcessData() getScreenImgProcessData();
getScreenGeneralizeData() getScreenGeneralizeData();
nextTick(() => { nextTick(() => {
initPieChart(); initPieChart();
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);

View File

@ -1,15 +1,15 @@
<template> <template>
<div class="large_screen"> <div class="large_screen">
<Header :projectId="projectId" :isFull="isFull" @changePage="handleChangePage" /> <Header :projectId="projectIdTwo ? projectIdTwo : projectId" :isFull="isFull" :projectName="projectName" @changePage="handleChangePage" />
<div class="nav"> <div class="nav">
<div class="nav_left" :style="{ left: isHideOther ? '-25vw' : '0' }"> <div class="nav_left" :style="{ left: isHideOther ? '-25vw' : '0' }">
<leftPage :projectId="projectId" /> <leftPage :projectId="projectIdTwo ? projectIdTwo : projectId" />
</div> </div>
<div class="nav_center" :style="{ width: isFull ? '100%' : 'calc(50vw - 30px)' }"> <div class="nav_center" :style="{ width: isFull ? '100%' : 'calc(50vw - 30px)' }">
<centerPage :projectId="projectId" :isHide="isFull" /> <centerPage :projectId="projectIdTwo ? projectIdTwo : projectId" :isHide="isFull" />
</div> </div>
<div class="nav_right" :style="{ right: isHideOther ? '-25vw' : '0' }"> <div class="nav_right" :style="{ right: isHideOther ? '-25vw' : '0' }">
<rightPage :projectId="projectId" /> <rightPage :projectId="projectIdTwo ? projectIdTwo : projectId" />
</div> </div>
</div> </div>
</div> </div>
@ -26,6 +26,10 @@ const userStore = useUserStoreHook();
const projectId = computed(() => userStore.selectedProject.id); const projectId = computed(() => userStore.selectedProject.id);
const isFull = ref(false); const isFull = ref(false);
const isHideOther = ref(false); const isHideOther = ref(false);
const urlParams = new URLSearchParams(new URL(window.location.href).search);
const projectIdTwo = urlParams.get('projectId');
const projectName = urlParams.get('projectName');
console.log(projectName);
/** /**
* 切换中心页面全屏 * 切换中心页面全屏