This commit is contained in:
2025-09-11 09:09:50 +08:00
5 changed files with 659 additions and 4 deletions

View File

@ -18,8 +18,10 @@ VITE_APP_BASE_API = 'http://192.168.110.149:8899'
#曾涛 #曾涛
# VITE_APP_BASE_API = 'http://192.168.110.171:8899' # VITE_APP_BASE_API = 'http://192.168.110.171:8899'
# 无人机接口地址 # ws
VITE_APP_BASE_WS_API = 'ws://192.168.110.149:8899/resource/websocket'
# 无人机接口地址
VITE_APP_BASE_DRONE_API = 'http://58.17.134.85:9512' VITE_APP_BASE_DRONE_API = 'http://58.17.134.85:9512'
# 应用访问路径 例如使用前缀 /admin/ # 应用访问路径 例如使用前缀 /admin/

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="ol-map" id="olMap"></div> <div class="ol-map" id="olMap"></div>
<div class="left_title_button"> <div class="left_title_button">
<div class="title">{{ projectName }}</div> <div class="title">{{ currentProject.name }}</div>
<div class="btn" @click="updateZhiJiaZhuanDian('zhuangdian')"> <div class="btn" @click="updateZhiJiaZhuanDian('zhuangdian')">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" /> <SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>桩点-更新高程</span> <span>桩点-更新高程</span>
@ -29,6 +29,11 @@
import { workScheduleDel } from '@/api/progress/plan'; import { workScheduleDel } from '@/api/progress/plan';
import { renderFacilitiesToCesium } from '@/views/gisHome/js/renderFacilities'; import { renderFacilitiesToCesium } from '@/views/gisHome/js/renderFacilities';
import { CenterHeight } from '@/views/gis2D/js/center'; import { CenterHeight } from '@/views/gis2D/js/center';
import { useUserStoreHook } from '@/store/modules/user';
const userStore = useUserStoreHook();
const currentProject = computed(() => userStore.selectedProject);
console.log('projectName', currentProject);
import md5 from 'js-md5'; import md5 from 'js-md5';
const arr = ref(); const arr = ref();
const initFacilities = async () => { const initFacilities = async () => {
@ -129,8 +134,10 @@ onMounted(async () => {
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) => {
createEarth();
console.log(res);
}); });
createEarth();
await handletilList(); await handletilList();
await initFacilities(); await initFacilities();
console.log(YJ); console.log(YJ);

628
src/views/gis2D/index2.vue Normal file
View File

@ -0,0 +1,628 @@
<template>
<div class="earth gis2D" id="earth">
<header-top :isShowTab="false" :isShowLog="false"></header-top>
<!-- <el-button class="btn" type="primary" @click="gengxin">更新</el-button> -->
<div class="left_title_button">
<div class="title">{{ projectName }}</div>
<div class="btn" @click="updateZhiJiaZhuanDian('zhuangdian')">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>桩点-更新高程</span>
</div>
<div class="btn" @click="updateHighLevel('nibianqi')">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>逆变器-更新高程</span>
</div>
<div class="btn" @click="updateHighLevel('xiangbian')">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>箱变-更新高程</span>
</div>
<div class="btn" @click="updateZhiJiaZhuanDian('zhijia')">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>支架-更新高程</span>
</div>
<div class="btn" @click="centerHeight()">
<SvgIcon :name="bottomSvg" :isStyle="true" :className="'width:250px;height:50px;'" />
<span>光伏板-更新高程</span>
</div>
</div>
<progressLoading :progress="progress" :tips="progressTips"></progressLoading>
</div>
</template>
<script lang="ts">
// import { toRefs, reactive, defineComponent, onMounted, getCurrentInstance, ref, nextTick } from 'vue';
// import { ElLoading, ElMessage } from 'element-plus';
// import headerTop from '../components/header/index.vue';
// import { NextLoading } from '/@/utils/loading';
// import { updateProjectId } from '/@/utils/tools';
// import { useUserInfo } from '/@/stores/userInfo';
// import progressLoading from '/@/components/progressLoading/index.vue';
// // 资源接口
// import { listQianqiMoxing } from '/@/api/system/qianqiManage/qianqiMoxing';
// import { manageAll, updateAll, gisList, gisListZhijia, ZhuangdianEdit_detail, ZhijiaEdit_detail } from '/@/api/gis2D/all';
// import { getSysProject } from '/@/api/system/sysProject';
// import bottomSvg from '/@/assets/svg/bottom.svg';
// // json字符判断
// import { typeJSON } from '/@/utils/toolsValidate';
// import { renderGuangfubanGlb } from '../utils/treeRender.js';
// import zjImage from '/@/assets/images/tree_icon/zhijia.png';
// import { Session } from '/@/utils/storage';
// import axios from 'axios';
// // import sign from '/@/utils/sign.js';
import zdImage from '/@/assets/images/tree_icon/zhuangdian.png';
let nibianqi = [];
let xiangbian = [];
let guanfuban = [];
let YJ = window.YJ;
// eslint-disable-next-line no-undef
export default defineComponent({
name: 'index',
components: {
headerTop,
progressLoading,
},
setup() {
const stores = useUserInfo();
const state = reactive({
projectId: stores.$state.userInfos.uprojectId,
queryParam: {
pageNum: 1,
pageSize: 10000000000,
projectId: stores.$state.userInfos.uprojectId,
},
projectName: '',
bottomSvg,
tools: null,
zhuangdian: {
// 桩点更新高层
originArr: [] as any[], //源数据数组
poiArr: [] as any[], //位置数据数组
},
zhijia: {
// 支架更新高层
originArr: [] as any[], //源数据数组
poiArr: [] as any[], //位置数据数组
},
gfbArr: [] as any[],
bbtArr: [] as any[],
progress: -1, //加载进度
progressTips: '数据更新中,请稍后……',
loading: null,
});
onMounted(() => {
// 关闭Loading效果
NextLoading.done();
createEarth();
// 切换项目 项目ID数据同步
let channel = new BroadcastChannel('BC-switchProject');
channel.addEventListener('message', function (e) {
if (e.data !== state.projectId) {
//保存更新项目id
updateProjectId(e.data);
location.reload(); //刷新页面
}
});
});
const initData = () => {
getRresource();
// 获取所有数据
getSourceAll();
// 项目名称
getProList(state.projectId);
// 获取桩点
getZhiJiaList();
getXZhuangDianList();
};
const commonJson = (item) => {
if (!item.detail) {
//是否存在
return false;
}
if (!typeJSON(item.detail)) {
//是否是JSON字符
return false;
}
return true;
};
// 渲染倾斜模型
const renderModel = (item) => {
let Nposition = {
lng: 0,
lat: 0,
alt: 0,
};
let position = null;
if (commonJson(item)) {
position = JSON.parse(item.detail).position || Nposition;
} else {
position = Nposition;
}
let options = {
id: item.sourceId,
host: '',
position,
show: true,
};
// eslint-disable-next-line no-undef
let model = new YJ.Zmkg.Source(options);
model.on().then((res) => {
if (model.source.tileset) {
let bim = model.source.tileset.czmObject;
}
setTimeout(() => {
if (model.id != 'dixing') {
model.flyTo();
}
}, 1000);
});
};
const getRresource = () => {
getQxModelList();
};
// 渲染光伏板
const redenrGfB = () => {
const loading = ElLoading.service({
lock: true,
text: '加载光伏板中....',
background: 'rgba(0, 0, 0, 0.7)',
});
let batchSize = 100;
for (let i = 0; i < guanfuban.length; i += batchSize) {
const batch = guanfuban.slice(i, i + batchSize);
renderGuangfubanGlb(batch);
}
loading.close();
};
// 获取所有的数据
const getSourceAll = () => {
const loading = ElLoading.service({
lock: true,
text: '获取数据中...',
background: 'rgba(0, 0, 0, 0.7)',
});
manageAll({ id: state.projectId }).then((res) => {
loading.close();
const { data } = res;
let list = data.data;
console.log('listlistlistlist', list);
if (list.length > 0) {
list.forEach((item: any) => {
if (item.type == 18) {
nibianqi.push(item);
}
if (item.type == 23) {
xiangbian.push(item);
}
if (item.type == 15) {
guanfuban.push(item);
}
});
let one = JSON.parse(guanfuban[0].detail);
if (one.height) {
redenrGfB();
} else {
ElMessage.warning('请优先更新光伏板');
}
}
});
};
// 删除光伏板数据
const removeSources = () => {
window['$PROJECT_MAP'].forEach((item) => {
// 清空地球上的实例
try {
item[0].remove();
} catch (error) {}
});
window['$PROJECT_MAP'].clear();
};
// 数组分组工具方法
const groupArr = (array, subGroupLength) => {
let index = 0;
let newArray = [];
while (index < array.length) {
newArray.push(array.slice(index, (index += subGroupLength)));
}
return newArray;
};
// 根据key去重
const duplicateRemoveByKey = (arr: any) => {
//根据key去重
let arrMap = new Map();
for (let item of arr) {
if (!arrMap.has(item.id)) {
arrMap.set(item.id, item);
}
}
arr = [...arrMap.values()]; //把map中所有的值取出来放进数组
return arr;
};
// 采样高层
const updateZhiJiaZhuanDian = async (type: any) => {
console.log(123);
let loading = null;
let load = false;
if (type == 'zhuangdian' && window.$PROJECT_MAP) {
removeSources();
load = true;
} else {
redenrGfB();
}
if (type != 'zhuangdian' && type != 'zhijia') {
loading = ElLoading.service({
lock: true,
text: '正在更新中',
background: 'rgba(0, 0, 0, 0.7)',
});
} else {
state.progress = 0;
}
console.log('statestatestatestatestate', state);
if (state[type].poiArr.length && state[type].originArr.length) {
let poiGroupArr = groupArr(state[type].poiArr, 500);
let oriGroupArr = groupArr(state[type].originArr, 500);
if (poiGroupArr.length) {
for (let i in poiGroupArr) {
await state.tools!.sampleHeightMostDetailed(poiGroupArr[i]).then((res: any) => {
if (res.length === oriGroupArr[i].length) {
// 返填重新赋值
oriGroupArr[i] = oriGroupArr[i].map((v: any, i: any) => {
let position = JSON.parse(v.detail);
if (type === 'zhijia') {
position.position.height = res[i].height ? res[i].height : 0;
} else {
position.position.alt = res[i].height ? res[i].height : 0;
}
v.detail = JSON.stringify(position);
return v;
});
state[type].originArr = [...state[type].originArr, ...oriGroupArr[i]];
state[type].originArr = duplicateRemoveByKey(state[type].originArr);
console.log(state[type].originArr);
state.progressTips = `总计${poiGroupArr.length}组数据,正在进行第${Number(i) + 1}组数据采样`;
state.progress = Number((((Number(i) + 1) / poiGroupArr.length) * 100).toFixed(2));
if (type === 'zhuangdian' || type === 'zhijia') {
// 全部采样完才请求接口
if (Number(i) - 0 == poiGroupArr.length - 1) {
updateAlt(type, loading);
}
} else {
updateAlt(type, loading);
}
} else {
loading?.close();
ElMessage.success('更新失败');
}
});
}
}
}
};
// 更新高层
const updateAlt = async (type: any, loading: any = null) => {
if (type === 'zhuangdian') {
chunkUpdateAlt(type, '/zm/api/v1/system/qianqiGuangfubanIdsZhuangdian/edit_detail');
}
if (type === 'zhijia') {
chunkUpdateAlt(type, '/zm/api/v1/system/qianqiGuangfubanIdsZhijia/edit_detail');
}
};
// 更新高程 分组请求接口(桩点 支架)
const chunkUpdateAlt = async (type: any, url: any) => {
state.progress = 0;
console.log(state.zhuangdian.originArr);
let list = state[type].originArr.map((item: any) => {
return JSON.parse(item.detail);
});
let groupList = groupArr(list, 5000);
if (groupList.length) {
for (let i in groupList) {
state.progressTips = `总计${groupList.length}组数据,正在进行第${Number(i) + 1}组数据更新`;
state.progress = Number(((Number(i) / groupList.length) * 100).toFixed(2));
await axios({
url: url,
method: 'put',
timeout: 0,
headers: {
Authorization: 'Bearer ' + `${Session.get('token')}`,
'Content-Type': 'application/json',
...sign({ projectId: state.projectId, list: groupList[i] }),
},
data: { projectId: state.projectId, list: groupList[i] },
})
.then((res: any) => {
if (res.data.code === 0) {
state.progress = 100;
ElMessage.success(`${Number(i) + 1}组数据更新成功,剩余${groupList.length - 1 - Number(i)}组数据`);
if (type === 'zhuangdian') {
getZhiJiaList();
}
} else {
ElMessage.error(res.data.message);
}
})
.catch((err) => {
ElMessage.error('请求失败');
});
}
}
};
// 获取支架列表
const getZhiJiaList = async () => {
state.zhijia.originArr = [];
state.zhijia.poiArr = [];
await gisListZhijia(state.queryParam).then((res: any) => {
console.log('list接口', res);
if (res.code === 0 && res.data.list) {
let arr = res.data.list.map((item, index) => {
item.p_id = '106';
item.checked = 1;
item.is_show = 1;
item.layer_index = 0;
item.icon = zjImage;
item.tree_index = 0;
let detail = null;
if (commonJson(item)) {
detail = JSON.parse(item.detail);
state.zhijia.originArr.push(item);
state.zhijia.poiArr.push({ lng: detail.position.lng, lat: detail.position.lat });
}
return item;
});
}
});
};
// 获取桩点的数据
const getXZhuangDianList = async () => {
await gisList(state.queryParam).then((res: any) => {
if (res.code === 0 && res.data.list) {
state.zhuangdian.poiArr = [];
let arr = res.data.list.map((item: any, index: any) => {
item.p_id = '102';
item.checked = 1;
item.is_show = 1;
item.layer_index = 0;
item.icon = zdImage;
item.tree_index = 0;
let detail = null;
if (commonJson(item)) {
detail = JSON.parse(item.detail);
state.zhuangdian.originArr.push(item);
state.zhuangdian.poiArr.push({ lng: detail.position.lng, lat: detail.position.lat });
}
return item;
});
}
});
};
// 获取中心点高程(光伏板)
const centerHeight = () => {
const loading = ElLoading.service({
lock: true,
text: '更新高程、中心点...',
background: 'rgba(0, 0, 0, 0.7)',
});
let arr = [];
guanfuban.forEach((item) => {
arr.push(JSON.parse(item.detail));
});
let heightAndCenter = window.YJ.Zmkg.Guangfu.CenterHeight(arr);
let center = heightAndCenter.center;
heightAndCenter.Cartographic.then((Cartographic: any) => {
if (Cartographic.length > 0) {
loading.close();
assemblingPhotovoltaicPanels(center, Cartographic);
}
});
};
// 组装高程数据
const assemblingPhotovoltaicPanels = async (center: any, height: any) => {
guanfuban.forEach((item, index) => {
let i = JSON.parse(item.detail);
i.height = height[index].height;
i.center = center[index];
item.detail = JSON.stringify(i);
});
let data = [...guanfuban];
let batchSize = 100000;
for (let i = 0; i < data.length; i += batchSize) {
const batch = data.slice(i, i + batchSize);
await updateElevation(batch);
}
getSourceAll();
};
// 更新高程(箱变、逆变器)
const updateHighLevel = (str: string) => {
let gxArr;
if (str == 'nibianqi') {
gxArr = nibianqi;
}
if (str == 'xiangbian') {
gxArr = xiangbian;
}
if (gxArr.length == 0) {
ElMessage({
message: '数据为空,请确认数据是否上传',
type: 'warning',
});
return;
}
let arr = [];
gxArr.forEach((item) => {
let p = JSON.parse(item.detail).positions[0];
arr.push(p);
});
const loading = ElLoading.service({
lock: true,
text: '更新高程中...',
background: 'rgba(0, 0, 0, 0.7)',
});
state.tools.sampleHeightMostDetailed(arr).then((Cartographic) => {
if (Cartographic.length > 0) {
loading.close();
assemblyData(gxArr, Cartographic);
}
});
};
// 组装数据
const assemblyData = (gxArr, arr) => {
gxArr.forEach((item, index) => {
let i = JSON.parse(item.detail);
i.positions[0].alt = arr[index].height;
item.detail = JSON.stringify(i);
});
updateElevation(gxArr);
};
// 更新高程(更新到后端)
const updateElevation = (gxArr) => {
const loading = ElLoading.service({
lock: true,
text: '上传中,请勿关闭页面...',
background: 'rgba(0, 0, 0, 0.7)',
});
updateAll({ Modules: gxArr }).then((res) => {
loading.close();
if (res.code == 0) {
ElMessage({
message: '上传成功',
type: 'success',
});
}
});
};
// 获取地形数据
const getQxModelList = () => {
listQianqiMoxing(state.queryParam).then((res: any) => {
if (res.code === 0 && res.data.list && res.data.list.length) {
res.data.list.forEach((item) => {
renderModel(item);
});
}
});
};
// 获取当前项目信息
const getProList = (id: any) => {
getSysProject(id).then((res: any) => {
const data = res.data;
state.projectName = data.projectName;
});
};
const createEarth = () => {
// eslint-disable-next-line no-undef
YJ.on().then((res: any) => {
// eslint-disable-next-line no-undef
let earth = new YJ.YJEarth('earth');
// // this.areaShow = true
// eslint-disable-next-line no-undef
new YJ.Layer.ArcgisWXImagery();
// // new YJ.Layer.ArcgisGRAYImagery()
// // new YJ.Layer.ArcgisBLUEImagery()
// // new YJ.Terrain.Arcgis()
// eslint-disable-next-line no-undef
new YJ.Layer.GDLWImagery();
// eslint-disable-next-line no-undef
state.tools = new YJ.Tools();
// eslint-disable-next-line no-undef
YJ.getEarth().propertyStyle = new Cesium.Cesium3DTileStyle({
// let stayle = new Cesium.Cesium3DTileStyle({
/*color: {
evaluateColor: (feature, result) => {
return bimTree.evaluateColor(feature, result)
}
},*/
show: {
evaluate: (feature) => {
return evaluateShow(feature);
},
},
});
initData();
});
};
// 监听模型加载显示隐藏
const evaluateShow = (feature: any) => {
return true;
if (!feature) return true;
if (!feature.hasProperty('id')) return true;
var fid = feature.getProperty('id');
// //获取tileset
var tileset = feature.tileset.xbsjTileset;
if (!tileset) return true;
// //寻找这个tileset上绑定的配置
var config = window._visibleConfig.find((f) => f.tileset === tileset);
if (!config) return true;
//如果配置里包含,那么返回可见性
if (config.visibleCach.hasOwnProperty(fid)) {
return config.visibleCach[fid];
} else return false;
//否则返回可见
};
return {
createEarth,
evaluateShow,
getRresource,
getQxModelList,
centerHeight,
commonJson,
updateHighLevel,
updateZhiJiaZhuanDian,
redenrGfB,
...toRefs(state),
};
},
});
</script>
<style scoped lang="scss">
.earth {
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
.left_title_button {
position: absolute;
top: 10%;
left: 30px;
width: 250px;
height: 100px;
z-index: 1999;
.title {
color: #fff;
font-weight: bold;
font-size: 22px;
margin-bottom: 20px;
}
.btn {
width: 100%;
height: 50px;
position: relative;
margin-bottom: 30px;
> span {
width: 100%;
font-size: 22px;
font-weight: bold;
color: #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
letter-spacing: 3px;
text-align: center;
}
}
}
}
</style>

View File

@ -781,6 +781,7 @@ const handleCheckRules = async (row?: ProjectVO) => {
const _id = row?.id || ids.value[0]; const _id = row?.id || ids.value[0];
const res = await byProjectIdDetail(_id); const res = await byProjectIdDetail(_id);
if (res.data) { if (res.data) {
console.log(res.data);
res.data.weekday = res.data.weekday.split(','); res.data.weekday = res.data.weekday.split(',');
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
} }
@ -794,7 +795,7 @@ const ruleSubmit = async () => {
let obj = { let obj = {
weekday: form.value.weekday.join(','), weekday: form.value.weekday.join(','),
projectId: projectId.value, projectId: projectId.value,
id: projectId.value, id: form.value.id,
clockInTime: form.value.clockInTime, clockInTime: form.value.clockInTime,
clockOutTime: form.value.clockOutTime, clockOutTime: form.value.clockOutTime,
type: form.value.type type: form.value.type

View File

@ -4,11 +4,26 @@ import CesiumImageLabelEntity from '../js/CesiumImageLabelEntity.js';
import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js'; import CesiumFlyToRoamingController from '../js/CesiumFlyToRoamingController.js';
import { setSelect, getSelectList, getGps } from '@/api/projectScreen/index.ts' import { setSelect, getSelectList, getGps } from '@/api/projectScreen/index.ts'
import videoDialog from "./video.vue" import videoDialog from "./video.vue"
import { getToken } from '@/utils/auth';
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);
let token = 'Bearer '+ 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');
// 连接ws
const connectWs = () => {
ws.onopen = (e) => {
// let message ={
// projectId:'1897160897167638529',
// }
// ws.send(JSON.stringify(message));
ws.onmessage = (e) => {
console.log('ws', e);
};
};
}
const props = defineProps({ const props = defineProps({
isHide:{ isHide:{
type:Boolean, type:Boolean,
@ -214,6 +229,8 @@ function stopRoaming() {
} }
} }
onMounted(() => { onMounted(() => {
// 连接ws
connectWs();
// 获取选中节点 // 获取选中节点
getCheckedNode(); getCheckedNode();
// 获取GPS数据 // 获取GPS数据