This commit is contained in:
zh
2025-09-25 16:21:00 +08:00
parent 5a0db4052d
commit 7d770ac126
99 changed files with 1686 additions and 291 deletions

View File

@ -12,7 +12,7 @@
"typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false",
"typecheck": "npm run typecheck:node && npm run typecheck:web",
"start": "electron-vite preview",
"dev": "electron-vite dev",
"dev": "chcp 65001 && electron-vite dev",
"build": "npm run typecheck && electron-vite build",
"postinstall": "electron-builder install-app-deps",
"build:unpack": "npm run build && electron-builder --dir",
@ -37,6 +37,7 @@
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1",
"scss": "^0.2.4",
"three": "^0.180.0",
"verror": "^1.10.1",
"vue-clipboard3": "^2.0.0",
"vue-i18n": "^9.14.5",

Binary file not shown.

View File

@ -12,11 +12,11 @@ let SERVER_PORTS = 55110;
* @param port
* @param cb
*/
let server
function portIsOccupied(port, cb) {
// 创建服务并监听该端口
port = Number(port);
let server = net.createServer().listen(port);
server = net.createServer().listen(port);
server.on("listening", function() {
// 执行这块代码说明端口未被占用
@ -61,14 +61,17 @@ function start() {
createApp();
portIsOccupied(SERVER_PORTS, (port) => {
// avilablePort挂载全局
// console.log(apps);
apps.listen(port);
server = apps.listen(port);
availablePort = port;
// console.log("global.sharedObject", global.avilablePort);
global.sharedObject.availablePort = port;
// ipcRenderer.invoke("set-global-variable", "avilablePort", avilablePort);
});
}
function getServer() {
return server
}
//获取项目根目录
// function GetHomeDir() {
// let HOME_DIR = process.cwd()
@ -85,4 +88,4 @@ ipcMain.handle('get-available-port', () => {
return availablePort;
});
export { apps, start };
export { apps, start, getServer };

View File

@ -7,7 +7,7 @@ import fs from 'fs'
import { exec } from 'child_process'
import dayjs from 'dayjs'
import { GetHomeDir } from './config'
import { start } from "./app";
import { start, getServer } from "./app";
// 开发环境路径处理 - 确保添加正确的file协议
@ -57,9 +57,9 @@ if (prodSplashPath) {
// 最终的启动页URL
const splashURL = process.env.NODE_ENV === 'development' ? devSplashURL : prodSplashURL
let startBatPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'start.bat')
let startBatPath = process.env.NODE_ENV === 'development' ? path.resolve(app.getAppPath(), 'resources', 'java', 'start.bat') : path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'start.bat')
startBatPath = process.platform === 'win32' ? startBatPath.replace(/^(\w:)/, '/$1') : startBatPath
let stopBatPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'stop.bat')
let stopBatPath = process.env.NODE_ENV === 'development' ? path.resolve(app.getAppPath(), 'resources', 'java', 'stop.bat') : path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'stop.bat')
stopBatPath = process.platform === 'win32' ? stopBatPath.replace(/^(\w:)/, '/$1') : stopBatPath
// const splashURL =
@ -126,7 +126,7 @@ function createWindow(): void {
}, 1000)
})
ipcMain.on('quit-app', () => {
app.quit()
windowAllClosed()
})
ipcMain.on('renderNode', () => {
// 获取所有窗口并转发消息
@ -254,7 +254,7 @@ function createWindow(): void {
ipcMain.handle('show-window-by-id', async (event, id) => {
BrowserWindow.fromId(id)?.show()
})
ipcMain.handle('get-_winMap',()=>{
ipcMain.handle('get-_winMap', () => {
return _winMap
})
// 设置窗口标题和图标
@ -332,36 +332,89 @@ app.whenReady().then(() => {
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
console.log('=================================================111111111', process.platform)
if (process.platform !== 'darwin') {
app.quit()
}
})
// app.on('window-all-closed', () => {
// if (process.platform !== 'darwin') {
// getServer().close(() => {
// // 关闭后台服务
// exec(stopBatPath.substring(1, 200), () => {
// app.quit()
// });
// })
// }
// })
// 退出时注销所有快捷键
app.on('will-quit', () => {
console.log('222222222222222222222')
// 关闭后台服务
exec(stopBatPath.substring(1, 200), (error, stdout, stderr) => {
dialog.showMessageBox({
type: 'info',
title: '信息1',
message: 'process.platform',
buttons: ['确定']
})
if (error) {
console.error(`执行错误: ${error.message}`);
return;
}
if (stderr) {
console.error(`错误输出: ${stderr}`);
return;
}
console.log(`批处理输出: ${stdout}`);
});
globalShortcut.unregisterAll()
})
// 用于跟踪是否正在执行退出流程
let isQuitting = false;
app.on('window-all-closed', () => {
windowAllClosed()
});
function windowAllClosed() {
// 防止重复触发退出流程
if (isQuitting) return;
isQuitting = true;
// macOS特殊处理保持应用活跃
if (process.platform === 'darwin') {
return;
}
console.log('所有窗口已关闭,执行清理脚本...');
getServer().close(() => {
// 执行批处理文件
const cleanupProcess = exec(stopBatPath.substring(1, 200), (error, stdout, stderr) => {
if (error) {
console.error(`清理脚本执行失败: ${error.message}`);
}
if (stderr) {
console.error(`清理脚本错误输出: ${stderr}`);
}
if (stdout) {
console.log(`清理脚本输出: ${stdout}`);
}
// 脚本执行完成后强制退出
forceQuit();
});
// 监听子进程退出事件(确保即使脚本出错也能退出)
cleanupProcess.on('exit', (code) => {
console.log(`清理脚本退出,代码: ${code}`);
if (isQuitting) {
forceQuit();
}
});
// 超时保护:防止脚本卡住导致应用无法退出
setTimeout(() => {
if (isQuitting) {
console.log('清理脚本执行超时,强制退出');
cleanupProcess.kill(); // 终止卡住的脚本
forceQuit();
}
}, 2000); // 2秒超时
})
}
// 强制退出应用的辅助函数
function forceQuit() {
// 终止所有剩余的子进程
if (process.platform === 'win32') {
// Windows系统特殊处理
exec('taskkill /F /T /PID ' + process.pid, (error) => {
if (error) console.error('强制终止失败:', error);
});
} else {
// 其他系统
process.exit(0);
}
}
console.log('=================================================')
global.sharedObject = {
hasService: false,

View File

@ -2495,7 +2495,7 @@
}
.el-select-dropdown__item {
font-size: 14px;
font-size: 12px;
padding: 0 20px;
position: relative;
white-space: nowrap;

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because one or more lines are too long

View File

@ -753,15 +753,13 @@
}
.YJ-custom-base-dialog>.content input[type=number] {
/* padding: 0 16px 0 10px;
font-weight: 700;
/* padding: 0 16px 0 10px; */
font-family: 'D-Din-Bold';
font-size: 18px; */
font-size: 12px;
font-size: 18px;
font-weight: 400;
letter-spacing: 0px;
line-height: 24px;
color: rgba(204, 204, 204, 1);
color: #ffffff;
text-align: left;
vertical-align: top;
}
@ -2212,6 +2210,7 @@
.YJ-custom-base-dialog.cut-fill>.content>div .div-item:last-child .row .unit {
margin-left: 5px;
}
.YJ-custom-base-dialog.cut-fill>.content .firstTip {
position: absolute;
left: 340px;
@ -2276,6 +2275,7 @@
flex: 0 0 60px;
justify-content: center;
}
.YJ-custom-base-dialog.submerge>.content .rangeWords {
font-size: 14px;
font-weight: 500;
@ -2437,6 +2437,7 @@
.YJ-custom-base-dialog.circle-view-shed>.content {
width: 290px;
}
.YJ-custom-base-dialog.circle-view-shed>.content .firstTip {
font-size: 14px;
font-weight: 700;
@ -3185,7 +3186,7 @@
}
/* 文本框 */
.popup-textarea{
.popup-textarea {
/* width: 212px; */
width: 161px;
/* height: 154px; */
@ -3198,28 +3199,30 @@
background-size: 100% 100%;
padding: 5px 5px 0px 5px;
}
.popup-textarea textarea{
.popup-textarea textarea {
width: 158px;
height: 95px;
background-color: unset!important;
border: unset!important;
background-color: unset !important;
border: unset !important;
color: #fff;
}
.popup-textarea textarea::-webkit-scrollbar {
width: 8px!important;
width: 8px !important;
/* height: 8px!important; */
}
.popup-textarea textarea::-webkit-scrollbar-thumb {
border-radius: 5px!important;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2)!important;
background-color: rgba(var(--color-sdk-base-rgb))!important;
border-radius: 5px !important;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2) !important;
background-color: rgba(var(--color-sdk-base-rgb)) !important;
}
.popup-textarea textarea::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2)!important;
border-radius: 5px!important;
background-color: rgba(var(--color-sdk-base-rgb), 0.1)!important;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2) !important;
border-radius: 5px !important;
background-color: rgba(var(--color-sdk-base-rgb), 0.1) !important;
}
/* 贴地图片 */
@ -3811,12 +3814,16 @@
border: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
border-right: none;
}
.billboard-attribute-box .table .tr .th, .billboard-attribute-box .table .tr .td {
.billboard-attribute-box .table .tr .th,
.billboard-attribute-box .table .tr .td {
border-right: 1px solid rgba(var(--color-sdk-base-rgb), 0.5);
display: flex;
justify-content: center;
}
.billboard-attribute-box .table .tr .th:last-child, .billboard-attribute-box .table .tr .td:last-child {
.billboard-attribute-box .table .tr .th:last-child,
.billboard-attribute-box .table .tr .td:last-child {
border-right: none;
}
@ -3865,6 +3872,7 @@
background-color: #f0f9eb;
color: rgb(82, 196, 26);
}
#YJ-custom-message.warning {
background-color: #fdf6ec;
color: #e6a23c;
@ -3889,8 +3897,8 @@
.yj-custom-icon {
display: inline-block;
width: 22px;
height: 10px;
width: 40px;
height: 20px;
margin-right: 5px;
}
@ -3964,3 +3972,33 @@
background: url(../../img/arrow/6.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall {
background: url(../img/icon-wall.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-gradient {
background: url(../img/icon-wall-gradient.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-arrow {
background: url(../../img/material/arrow.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-warn {
background: url(../../img/material/warn.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-brick1 {
background: url(../../img/material/brick1.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-brick2 {
background: url(../../img/material/brick2.png) 100% 100% no-repeat;
background-size: 100% 100%;
}
.yj-custom-icon.icon-wall-brick3 {
background: url(../../img/material/brick3.png) 100% 100% no-repeat;
background-size: 100% 100%;
}

Binary file not shown.

View File

@ -68,20 +68,20 @@ export default {
},
effect: {
trajectoryMotion: "轨迹运动",
electronicFence: "电子围墙",
// nightVision: '实体墙',
radarLightWave: "扩散光波",
diffusedLightWave: "雷达光波",
wallStereoscopic: "电子围墙",
entityWall: '实体墙',
diffuseScan: "扩散光波",
radarScan: "雷达光波",
scanStereoscopic: "立体雷达",
multilateralBody: "多边体",
waterSurface: "水面",
polyhedronObject: "多边体",
water: "水面",
fountain: '喷泉',
waterL: '水柱',
fire: "火焰",
explosion: "爆炸",
smoke: "烟雾",
nightVision: '夜视',
// nightVision: '飞线',
flyLine: '飞线',
},
analysis: {
inundationAnalysis: "淹没分析",
@ -115,7 +115,7 @@ export default {
graffiti: "涂鸦",
// stopGraffiti: "结束涂鸦",
clearGraffiti: "清除涂鸦",
path: "飞行漫游",
roam: "飞行漫游",
coorLocation: "坐标定位",
mouseLocation: "鼠标定位",
annotationAggregation: "标注点聚合",

View File

@ -68,7 +68,7 @@ export default {
pressModel: 'press Model',
terrainDig: 'terrainDig',
pictureLocation: 'pictureLocation',
path: 'path',
roam: 'roam',
annotationAggregation: 'MarkPoint',
mouseLocation: 'mouseLocation',
mouseOver: 'mouseOver',
@ -83,13 +83,13 @@ export default {
fire: 'fire',
smoke: 'smoke',
explosion: 'explosion',
waterSurface: 'waterSurface',
radarLightWave: 'radar',
diffusedLightWave: 'diffused',
water: 'waterSurface',
diffuseScan: 'radar',
radarScan: 'diffused',
scanStereoscopic: 'scanStereoscopic',
electronicFence: 'elecFence',
wallStereoscopic: 'elecFence',
entityWall: 'entityWall',
multilateralBody: 'multilateral',
polyhedronObject: 'multilateral',
clearTrajectoryMotion: 'clearTrajectoryMotion',
cube: 'cube',
trajectoryMotion: 'trackMotion',
@ -112,12 +112,12 @@ export default {
standText: 'StandText',
// fire: "fire",
// waterSurface: "waterSurface",
// water: "waterSurface",
// annotationAggregation: "annotationAggregation",
// radarLightWave: "radarLightWave",
// diffusedLightWave: "diffusedLightWave",
// electronicFence: "electronicFence",
// multilateralBody: "multilateralBody",
// diffuseScan: "radarLightWave",
// radarScan: "diffusedLightWave",
// wallStereoscopic: "electronicFence",
// polyhedronObject: "multilateralBody",
// cube: "cube",
// trajectoryMotion: "trajectoryMotion",
// roadDraw: "roadDraw",

View File

@ -61,7 +61,7 @@ export default {
terrainDig: '地形開挖',
pictureLocation: '照片定位',
importPanorama: '全景導入',
path: '飛行漫遊',
roam: '飛行漫遊',
annotationAggregation: '標註點聚合',
mouseLocation: '鼠標定位',
mouseOver: '結束定位',
@ -75,14 +75,14 @@ export default {
fire: '火焰',
smoke: '烟霧',
explosion: '爆炸',
waterSurface: '水面',
radarLightWave: '擴散光波',
diffusedLightWave: '雷達光波',
water: '水面',
diffuseScan: '擴散光波',
radarScan: '雷達光波',
clearTrajectoryMotion: '清除軌跡',
scanStereoscopic: '立體雷達',
electronicFence: '電子圍墻',
wallStereoscopic: '電子圍墻',
entityWall: '物體牆',
multilateralBody: '多邊體',
polyhedronObject: '多邊體',
cube: '立方體',
trajectoryMotion: '軌跡運動',
roadDraw: '道路繪製',

View File

@ -9,6 +9,9 @@ export const TreeApi = {
},
// 新增资源 /source/addModelSource
addModelSource: async (data: any) => {
if (!data.treeIndex) {
data.treeIndex = getTreeIndex()
}
return await request.post({
url: `/source/addModelSource`,
data
@ -16,6 +19,9 @@ export const TreeApi = {
},
// 新增其他资源 /source/addOtherSource
addOtherSource: async (data: any) => {
if (!data.treeIndex) {
data.treeIndex = getTreeIndex()
}
return await request.post({
url: `/source/addOtherSource`,
data
@ -29,6 +35,9 @@ export const TreeApi = {
//新增目录
addDirectory: async (data: any) => {
if (!data.treeIndex) {
data.treeIndex = getTreeIndex()
}
return await request.post({
url: `/source/addDirectory`,
data
@ -68,3 +77,44 @@ export const TreeApi = {
})
}
}
const getTreeIndex = () => {
let nodes = window.treeObj.getSelectedNodes();
// 获取最大tree_index的辅助函数
const getMaxTreeIndex = (items: any = []) => items.reduce((max, item) => Math.max(max, item.treeIndex || 0), 0);
if (nodes.length > 0) {
// 检查当前节点是否有子节点
let children = nodes[0].children;
if (children && children.length > 0) {
// 从子节点中获取最大tree_index
return getMaxTreeIndex(children) + 1;
} else {
// 获取父节点
let parentNode = nodes[0].getParentNode();
if (parentNode) {
// 从父节点的子节点中获取最大tree_index
return getMaxTreeIndex(parentNode.children) + 1;
} else {
// 没有父节点,获取根节点列表
let nodes = window.treeObj.getNodes();
if (nodes.length > 0) {
return getMaxTreeIndex(nodes) + 1;
} else {
return nodes.length + 1;
}
}
}
} else {
// 没有选中节点,获取根节点列表
// 获取根节点列表,处理可能为undefined的情况
const nodes = window.treeObj.getNodes() || [];
let max
if (nodes.length > 0) {
max = getMaxTreeIndex(nodes)
} else {
max = nodes.length
}
return max + 1;
}
}

View File

@ -72,7 +72,7 @@ module.exports = {
pressModel: "press Model",
terrainDig: "terrainDig",
pictureLocation: "pictureLocation",
path: "path",
roam: "roam",
annotationAggregation: "MarkPoint",
mouseLocation: "mouseLocation",
mouseOver: "mouseOver",
@ -87,13 +87,13 @@ module.exports = {
fire: "fire",
smoke: "smoke",
explosion: "explosion",
waterSurface: "waterSurface",
radarLightWave: "radar",
diffusedLightWave: "diffused",
water: "waterSurface",
diffuseScan: "radar",
radarScan: "diffused",
scanStereoscopic: "scanStereoscopic",
electronicFence: "elecFence",
wallStereoscopic: "elecFence",
entityWall: "entityWall",
multilateralBody: "multilateral",
polyhedronObject: "multilateral",
clearTrajectoryMotion: "clearTrajectoryMotion",
cube: "cube",
trajectoryMotion: "trackMotion",
@ -116,12 +116,12 @@ module.exports = {
standText: "StandText",
// fire: "fire",
// waterSurface: "waterSurface",
// water: "waterSurface",
// annotationAggregation: "annotationAggregation",
// radarLightWave: "radarLightWave",
// diffusedLightWave: "diffusedLightWave",
// electronicFence: "electronicFence",
// multilateralBody: "multilateralBody",
// diffuseScan: "radarLightWave",
// radarScan: "diffusedLightWave",
// wallStereoscopic: "electronicFence",
// polyhedronObject: "multilateralBody",
// cube: "cube",
// trajectoryMotion: "trajectoryMotion",
// roadDraw: "roadDraw",

View File

@ -65,7 +65,7 @@ module.exports = {
terrainDig: "地形開挖",
pictureLocation: "照片定位",
importPanorama: "全景導入",
path: "飛行漫遊",
roam: "飛行漫遊",
annotationAggregation: "標註點聚合",
mouseLocation: "鼠標定位",
mouseOver: "結束定位",
@ -79,14 +79,14 @@ module.exports = {
fire: "火焰",
smoke: "烟霧",
explosion: "爆炸",
waterSurface: "水面",
radarLightWave: "擴散光波",
diffusedLightWave: "雷達光波",
water: "水面",
diffuseScan: "擴散光波",
radarScan: "雷達光波",
clearTrajectoryMotion: "清除軌跡",
scanStereoscopic: "立體雷達",
electronicFence: "電子圍墻",
wallStereoscopic: "電子圍墻",
entityWall: "物體牆",
multilateralBody: "多邊體",
polyhedronObject: "多邊體",
cube: "立方體",
trajectoryMotion: "軌跡運動",
roadDraw: "道路繪製",

View File

@ -69,7 +69,7 @@ module.exports = {
terrainDig: '地形开挖',
splitScreen: '卷帘对比',
path: '飞行漫游',
roam: '飞行漫游',
annotationAggregation: '标注点聚合',
mouseLocation: '鼠标定位',
mouseOver: '结束定位',
@ -83,13 +83,13 @@ module.exports = {
fire: '火焰',
smoke: '烟雾',
explosion: '爆炸',
waterSurface: '水面',
radarLightWave: '扩散光波',
diffusedLightWave: '雷达光波',
water: '水面',
diffuseScan: '扩散光波',
radarScan: '雷达光波',
scanStereoscopic: '立体雷达',
electronicFence: '电子围墙',
wallStereoscopic: '电子围墙',
entityWall: '实体墙',
multilateralBody: '多边体',
polyhedronObject: '多边体',
cube: '立方体',
trajectoryMotion: '轨迹运动',
clearTrajectoryMotion: '清除轨迹',

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

View File

@ -28,7 +28,7 @@
linear-gradient(to right, rgba(0, 255, 255, 0.3) 0%, rgba(0, 255, 255, 0) 100%),
rgba(0, 0, 0, 0.8);
--bg-color1: rgba(0, 255, 255, 0.2);
font-size: calc(10px + 0.2vw); //
font-size: calc(10px + 0.2vw);
}
@media (max-width: 768px) {
:root {
@ -272,6 +272,21 @@ img {
.YJ-custom-checkbox-right {
top: 6.5vw !important;
}
.YJ-custom-base-dialog .el-select__wrapper{
background-color: rgba(0, 255, 255, 0.2);
font-size: 12px;
box-shadow: none;
font-size: 12px;
}
.YJ-custom-base-dialog .el-select__wrapper.is-focused,
.YJ-custom-base-dialog .el-select__wrapper.is-hovering:not(.is-focused) {
box-shadow: none;
}
.YJ-custom-base-dialog .el-select__wrapper .el-select__placeholder, .YJ-custom-base-dialog .el-select__wrapper.is-focused .el-select__placeholder{
color: #fff;
display: flex;
align-items: center;
}
.el-select__popper.el-popper{
background: transparent !important;
border: none !important; /* 去除边框 */
@ -297,7 +312,7 @@ img {
.el-select-dropdown__item {
color: #fff !important; /* 文字颜色 */
font-size: 12px !important;
}
/* 修改选中项的样式 */
.el-select-dropdown__item.is-selected {
@ -319,6 +334,28 @@ img {
background: transparent !important;
border: none !important;
}
/* 树 */
.ztree li span.button.ico_docu {
background:url(../images/tree/folder-empty.png) 0 0 no-repeat;
background-size: 100% 100% !important;
background-position: center !important;
}
.ztree li span.button.ico_close {
background:url(../images/tree/folder-close.png) 0 0 no-repeat;
background-size: 100% 100% !important;
background-position: center !important;
}
.ztree li span.button.ico_open {
background:url(../images/tree/folder-open.png) 0 0 no-repeat;
background-size: 100% 100% !important;
background-position: center !important;
}
.ztree li span.button.ico_docu:not([style=""]) {
background-size: 90% 90% !important;
background-position: center !important;
/* margin-top: 1px; */
}
/* 提示 */
/* .el-message--info {
background: rgba(0, 0, 0, 0.5) !important;

View File

@ -88,6 +88,9 @@ export const initMapData = async (type, data, cd) => {
case 'wallStereoscopic':
entityObject = new YJ.Obj.WallStereoscopic(window.earth, data)
break
case 'entityWall':
entityObject = new YJ.Obj.WallRealStereoscopic(window.earth, data)
break
case 'diffuseScan':
entityObject = new YJ.Obj.CircleDiffuse(window.earth, data)
break
@ -98,7 +101,7 @@ export const initMapData = async (type, data, cd) => {
entityObject = new YJ.Obj.RadarScanStereoscopic(window.earth, data)
break
case 'textBox':
entityObject = new YJ.Obj.TextBox(window.earth, data)
entityObject = new YJ.Obj.TextBox(window.earth, data, ()=>{})
break
case 'polyhedronObject':
entityObject = new YJ.Obj.PolyhedronObject(window.earth, data)
@ -106,6 +109,24 @@ export const initMapData = async (type, data, cd) => {
case 'water':
entityObject = new YJ.Obj.WaterSurface(window.earth, data)
break
case 'fountain':
entityObject = new YJ.Obj.Fountain(window.earth, data)
break
case 'fire':
entityObject = new YJ.Obj.Flame(window.earth, data)
break
case 'smoke':
entityObject = new YJ.Obj.Smoke(window.earth, data)
break
case 'waterL':
entityObject = new YJ.Obj.Spout(window.earth, data)
break
case 'flyLine':
entityObject = new YJ.Obj.FlowLine(window.earth, data)
break
case 'explosion':
entityObject = new YJ.Obj.Explosion(window.earth, data)
break
default:
break
}
@ -117,11 +138,19 @@ export const initMapData = async (type, data, cd) => {
case 'textBox':
delete options.name
break
case 'fountain':
case 'fire':
case 'smoke':
case 'waterL':
delete options.url
break
default:
break
}
console.log('--------------------onClick')
//鼠标左键点击事件
entityObject.onClick = () => {
// console.log('onClick')
leftClick(options);
};
//鼠标右键点击事件

View File

@ -4,13 +4,6 @@
:class="className"
ref="baseDialog"
:id="id"
:style="{
width: width,
height: height,
top: top,
left: left,
position: fix ? 'fixed' : 'absolute'
}"
v-if="dialogVisible"
v-show="dialogVisible"
>
@ -128,11 +121,18 @@ const open = (data) => {
})
}
dialogVisible.value = true
// nextTick(() => {
// setTimeout(() => {
// openPosition()
// }, 0)
// })
nextTick(() => {
// setTimeout(() => {
// openPosition()
// }, 0)
if(baseDialog.value) {
baseDialog.value.style.width = props.width
baseDialog.value.style.height = props.height
baseDialog.value.style.top = props.top
baseDialog.value.style.left = props.left
baseDialog.value.style.position = props.fix ? 'fixed' : 'absolute'
}
})
}
const close = () => {

View File

@ -75,12 +75,13 @@ const add = throttle(async () => {
let addNode = await cusAddNodes(window.treeObj, getSelectedNode(window.treeObj), [node], true) //添加节点
//获取该节点下的同级节点
const someNode: any = getSameLevel(window.treeObj, addNode[0])
console.log('someNode', someNode)
const newNode = someNode.map((item: any) => {
let index = item.getIndex()
item.tree_index = index
item.treeIndex = index+1
return {
...item,
tree_index: item.getIndex()
treeIndex: item.getIndex()
}
})
ElMessage({
@ -101,7 +102,7 @@ const updateTree = async (newNode: any) => {
const list = newNode.map((item: any) => {
return {
id: item.id,
tree_index: item.tree_index,
treeIndex: item.treeIndex,
parentId: item.parentId
}
})

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -189,6 +189,7 @@ const closeDialog = () => {
modelType.value = ''
dialogVisible.value = false
}
//@ts-ignore
const addType = () => {
if (!modelType.value) {
return ElMessage.warning('请输入模型类型名称')
@ -352,7 +353,7 @@ const allowDrag = (draggingNode: Node) => {
//拖拽结束
//---------------------查看缩略图--------------------
var showImageRow = null
var showImageRow:any = null
const showImage = (row: any) => {
showImageRow = row
eventBus.emit('imagePopDialog', row)
@ -628,6 +629,7 @@ const handleDelete = (row: ModelItem) => {
ModelApi.delModel(formData).then((res) => {
if (res.code == 0 || res.code == 200) {
ElMessage.success('删除成功')
// @ts-ignore
getModelListByType(row.modelTypeId)
}
})

View File

@ -66,18 +66,20 @@ const menuList: any = ref([
key: 'effect',
children: [
'trajectoryMotion',
'electronicFence',
'wallStereoscopic',
'entityWall',
// "nightVision",
'radarLightWave',
'diffusedLightWave',
'diffuseScan',
'radarScan',
'scanStereoscopic',
'multilateralBody',
'waterSurface',
'polyhedronObject',
'water',
'fountain',
'waterL',
'fire',
'explosion',
'smoke',
'flyLine',
'nightVision'
// "nightVision",
]
@ -134,7 +136,7 @@ const menuList: any = ref([
'graffiti',
// stopGraffiti: "结束涂鸦",
'clearGraffiti',
'path',
'roam',
'coorLocation',
'mouseLocation',
'annotationAggregation',

View File

@ -3,7 +3,7 @@
<div class="leftSideSecondBox">
<template v-if="obj">
<div class="menuItem" v-for="value in obj.children" @click="handleClick(value)">
<img :src="'src/assets/images/second/' + `${value}` + '.png'" style="color: rgb(255, 0, 0)" alt="" />
<img :src="'http://localhost:'+`${availablePort}`+ '/icon/' + `${value}` + '.png'" style="color: rgb(255, 0, 0)" alt="" />
<!-- <svg-icon :name="value" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon> -->
<span :style="{ color: !clickChange[value] ? 'var(--color-text)' : 'rgb(255,0,0)' }">{{
t(`${obj.key}.${value}`)
@ -33,6 +33,10 @@ const { ipcRenderer } = require('electron')
const { t } = useI18n()
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
const fs = require('fs')
const availablePort = ref(55110);
ipcRenderer.invoke('get-available-port').then((port)=>{
availablePort.value = port
})
const obj: any = ref(null)
const isclick = ref(false)
const eventBus: any = inject('bus')
@ -43,7 +47,8 @@ var clickChange = reactive({
mouseLocation: false,
annotation: false,
annotationAggregation: false,
videoRecord: false
videoRecord: false,
nightVision: false
})
var graffitiObjArr = reactive([])
eventBus.on('graffitiObj', (data: never) => {
@ -86,35 +91,36 @@ window.addEventListener('keydown', handleKeyDown)
const methodMap = {
// 轨迹运动
trajectoryMotion: async() => {
let availablePort = await ipcRenderer.invoke('get-available-port');
let draw = new YJ.Draw.DrawPolyline(window.earth)
draw.start(async (err, positions) => {
if (positions && positions.length > 1) {
let id = new YJ.Tools().randomString()
let name = '轨迹运动'
await addMapSource({
type: 'path',
id: id,
sourceName: name,
opt: {
trajectoryMotion: async () => {
eventBus.emit('openModel', true, (url) => {
let draw = new YJ.Draw.DrawPolyline(window.earth)
draw.start(async (err, positions) => {
if (positions && positions.length > 1) {
let id = new YJ.Tools().randomString()
let name = '轨迹运动'
await addMapSource({
type: 'path',
id: id,
name: name,
model: {
show: true,
url: `http://localhost:${availablePort}/tank.glb`
},
line: {
show: true,
positions: positions
sourceName: name,
opt: {
id: id,
name: name,
model: {
show: true,
url: url
},
line: {
show: true,
positions: positions
}
}
}
})
}
})
})
}
})
}, 'trajectoryMotion')
},
// 电子围墙
electronicFence: () => {
wallStereoscopic: () => {
let draw = new YJ.Draw.DrawPolyline(window.earth)
draw.start((err, positions) => {
if (positions.length > 1) {
@ -133,8 +139,28 @@ const methodMap = {
}
})
},
// 实体墙
entityWall: () => {
let draw = new YJ.Draw.DrawPolyline(window.earth)
draw.start((err, positions) => {
if (positions.length > 1) {
let id = 'aaa'
let name = '实体墙'
addMapSource({
type: 'entityWall',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
positions: positions
}
})
}
})
},
// 扩散光波
radarLightWave: () => {
diffuseScan: () => {
let draw = new YJ.Draw.DrawCircle(window.earth)
draw.start((err, options) => {
console.log('options', options)
@ -162,7 +188,7 @@ const methodMap = {
})
},
// 雷达光波
diffusedLightWave: () => {
radarScan: () => {
let draw = new YJ.Draw.DrawCircle(window.earth)
draw.start((err, options) => {
console.log('options', options)
@ -208,7 +234,7 @@ const methodMap = {
})
},
// 多面体
multilateralBody: () => {
polyhedronObject: () => {
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, positions) => {
if (!positions || positions.length < 3) {
@ -232,7 +258,8 @@ const methodMap = {
})
})
},
waterSurface: () => {
// 水面
water: () => {
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, positions) => {
if (!positions || positions.length < 3) {
@ -256,6 +283,156 @@ const methodMap = {
})
})
},
// 喷泉
fountain: () => {
let draw = new YJ.Draw.DrawPoint(window.earth)
draw.start(async (a, position) => {
if (!position) {
return
}
let id = new YJ.Tools().randomString()
let name = '喷泉'
await addMapSource({
type: 'fountain',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
lng: position.lng,
lat: position.lat,
alt: position.alt,
}
})
})
},
// 火焰
fire: () => {
let draw = new YJ.Draw.DrawPoint(window.earth)
draw.start(async (a, position) => {
if (!position) {
return
}
let id = new YJ.Tools().randomString()
let name = '火焰'
await addMapSource({
type: 'fire',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
lng: position.lng,
lat: position.lat,
alt: position.alt,
}
})
})
},
// 烟雾
smoke: () => {
let draw = new YJ.Draw.DrawPoint(window.earth)
draw.start(async (a, position) => {
if (!position) {
return
}
let id = new YJ.Tools().randomString()
let name = '烟雾'
await addMapSource({
type: 'smoke',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
lng: position.lng,
lat: position.lat,
alt: position.alt,
}
})
})
},
// 喷射水柱
waterL: () => {
let draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 })
draw.start(async (a, positions) => {
if (!positions || positions.length < 2) {
ElMessage({
message: '至少需要绘制两个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
let name = '喷射水柱'
await addMapSource({
type: 'waterL',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
start: {
...positions[0]
},
end: {
...positions[1]
}
}
})
})
},
// 飞线
flyLine: () => {
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, positions) => {
if (!positions || positions.length < 3) {
ElMessage({
message: '至少需要绘制三个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
let name = '飞线'
addMapSource({
type: 'flyLine',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
positions: positions
}
})
})
},
// 爆炸
explosion: () => {
let draw = new YJ.Draw.DrawPoint(window.earth)
draw.start(async (a, position) => {
if (!position) {
return
}
let id = new YJ.Tools().randomString()
let name = '爆炸'
await addMapSource({
type: 'explosion',
id: id,
sourceName: name,
opt: {
id: id,
name: name,
position: position
}
})
})
},
// 夜视
nightVision: () => {
clickChange.nightVision = !clickChange.nightVision
YJ.Global.efflect.nightVision(window.earth, clickChange.nightVision);
},
//投影面积
projectionArea: () => {
new YJ.Measure.MeasureTyArea(window.earth).start()
@ -363,8 +540,8 @@ const methodMap = {
item.remove()
})
},
//路径
path() {
//漫游
roam() {
eventBus.emit('flyRoamDialog')
},
//坐标定位

View File

@ -0,0 +1,132 @@
<template>
<Dialog ref="baseDialog" title="爆炸属性" left="180px" top="100px" className="explosion"
:closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" v-model="entityOptions.name">
</div>
<div class="col" style="flex: 0 0 120px">
<span class="label">随地图缩放</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.scaleByDistance" />
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" v-model="entityOptions.lng">
</div>
<div class="col">
<span class="label">爆炸范围</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="999999" v-model="entityOptions.size">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat">
</div>
<div class="col">
<span class="label">高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="-9999999" max="999999999" v-model="entityOptions.alt">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<div style="position: absolute; left: 24px; display: flex;">
<button style="margin-left: 10px;" @click="translate"><svg class="icon-py">
<use xlink:href="#yj-icon-py"></use>
</svg>平移</button>
</div>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { inject } from 'vue'
import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue'
import { useTreeNode } from '../tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open()
})
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.reset()
eventBus.emit("destroyComponent")
}
const open = async (id: any) => {
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
}
const translate = () => {
if(that.positionEditing) {
that.closePositionEditing()
}
else {
that.openPositionEditing(()=>{
entityOptions.value.lng = entityOptions.value.lng
entityOptions.value.lat = entityOptions.value.lat
entityOptions.value.alt = entityOptions.value.alt
})
}
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
delete params.host
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
that.remove()
close()
}
defineExpose({
open,
close
})
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,156 @@
<template>
<Dialog ref="baseDialog" title="飞线属性" left="180px" top="100px" className="flow-line-surface"
:closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" v-model="entityOptions.name">
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color" ref="colorRef"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">飞线数量</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="1" max="99999" v-model="entityOptions.pointNumber">
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">飞线宽度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" max="99999" min="1" step="1" v-model="entityOptions.width">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">飞线高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="0" max="999999" step="1" v-model="entityOptions.height">
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">飞线高度差</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" max="99999" min="0" step="1" v-model="entityOptions.heightDifference">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">单次运动时长s</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" max="999999999" min="1" step="1" v-model="entityOptions.duration">
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">轨迹透明度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" max="1" min="0.01" step="0.01" v-model="entityOptions.lineBackAlpha">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { inject } from 'vue'
import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue'
import { useTreeNode } from '../tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const colorRef = ref(null)
eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open()
})
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.reset()
eventBus.emit("destroyComponent")
}
const open = async (id: any) => {
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
new (window as any).YJColorPicker({
el: colorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: (color) => {
entityOptions.value.color = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
delete params.host
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
that.remove()
close()
}
defineExpose({
open,
close
})
</script>
<style scoped lang="scss"></style>

View File

@ -59,7 +59,7 @@ eventBus.on('imagePopDialog', (data) => {
})
})
//----------------模型预览---------------
const threeCanvas = ref(null)
const threeCanvas:any = ref(null)
let scene, camera, renderer, model, controls
const initThreeJS = () => {

View File

@ -63,6 +63,7 @@ const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = {
layerIndex: entityOptions.value.layerIndex,
alpha: entityOptions.value.alpha,
brightness: entityOptions.value.brightness,
name: entityOptions.value.name,

View File

@ -121,7 +121,7 @@ interface Category {
}
// 模拟数据
const categories = ref<Category[]>([])
const categories = ref<any[]>([])
const activeTab = ref('0')
const galleryRef = ref<HTMLElement>()
@ -225,7 +225,7 @@ const toggleExpand = (row: any) => {
currentTypeId.value = row.id
// loadModelsByType(row.id)
}
const addType = ref('')
let typeArr = {
point: '点',
line: '线',
@ -240,6 +240,13 @@ const modelClick = (index, row) => {
// return
// }
// 轨迹运动选择模型
if(selectCallback && typeof selectCallback === 'function' && addType.value === 'trajectoryMotion'){
selectCallback('http://127.0.0.1:8848' + row.data)
close()
return
}
if (!isSetting) {
ElMessage.warning('请先设置模型默认参数')
return
@ -303,7 +310,7 @@ const renderModel = async (data, model) => {
}
let Model = await new YJ.Obj.Model(window.earth, option)
let DbOption = {
let DbOption:any = {
params: option,
id,
sourceName: model.modelName + index,
@ -380,7 +387,9 @@ onBeforeUnmount(() => {
})
//end
eventBus.on('openModel', (data) => {
eventBus.on('openModel', (data, cb, type) => {
selectCallback = cb
addType.value = type
isShowPup.value = data
if (data) {
getModelList()
@ -388,6 +397,8 @@ eventBus.on('openModel', (data) => {
}
})
eventBus.on('closeModelSet', (data) => {
addType.value = ''
selectCallback = null
isShowPup.value = data
if (data) {
console.log('设置后')
@ -396,7 +407,7 @@ eventBus.on('closeModelSet', (data) => {
})
//查看是否有设置模型设置
var isSetting = null
var isSetting:any = null
const getSetting = () => {
ModelApi.getModelSetting().then((res) => {
if (res.code == 0 || res.code == 200) {
@ -409,13 +420,18 @@ const open = () => {
isShowPup.value = true
}
const close = () => {
addType.value = ''
selectCallback = null
isShowPup.value = false
}
const setting = () => {
isShowPup.value = false
// @ts-ignore
eventBus.emit('openModelSetting', (true, isSetting))
}
let selectCallback:any = null
defineExpose({
open,
close

View File

@ -242,13 +242,11 @@
<div style="position: absolute; left: 24px; display: flex">
<button @click="nodeEdit">
<svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use></svg
>二次编辑
<use xlink:href="#yj-icon-edit"></use></svg>二次编辑
</button>
<button style="margin-left: 10px" @click="translate">
<svg class="icon-py">
<use xlink:href="#yj-icon-py"></use></svg
>平移
<use xlink:href="#yj-icon-py"></use></svg>平移
</button>
</div>
<button @click="remove">删除</button>
@ -423,11 +421,11 @@ const translate = () => {
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.closeNodeEdit()
entityOptions.value.reset()
eventBus.emit('destroyComponent')
// entityOptions.value.originalOptions = structuredClone(originalOptions)
// that.positionEditing = false
// entityOptions.value.closeNodeEdit()
// entityOptions.value.reset()
// eventBus.emit('destroyComponent')
}
const nodeEdit = () => {

View File

@ -0,0 +1,334 @@
<template>
<Dialog ref="baseDialog" :title="title + '属性'" left="180px" top="100px" className="particle-effects"
:closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name" />
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" v-model="entityOptions.lng" />
</div>
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat" />
</div>
</div>
<div class="row">
<div class="col">
<span class="label">高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" v-model="entityOptions.alt">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<span class="label">起始颜色</span>
<div class="start_color" ref="startColorRef"></div>
</div>
<div class="col" style="margin: 0;justify-content: flex-end;">
<span class="label">结束颜色</span>
<div class="end_color" ref="endColorRef"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item" v-if="title !== '喷射水柱'">
<div class="row">
<div class="col">
<div class="row">
<span>最小初速度</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.minimumSpeed">
</div>
</div>
<div class="col">
<div class="row">
<span>最大初速度</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.maximumSpeed">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>最小存在时间</span>
<input type="range" max="100" min="0.01" step="0.1" v-model="entityOptions.minimumParticleLife">
</div>
</div>
<div class="col">
<div class="row">
<span>最大存在时间</span>
<input type="range" max="100" min="0.01" step="0.1" v-model="entityOptions.maximumParticleLife">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>起始比例</span>
<input type="range" max="10" min="0" step="0.1" v-model="entityOptions.startScale">
</div>
</div>
<div class="col">
<div class="row">
<span>结束比例</span>
<input type="range" max="10" min="0" step="0.1" v-model="entityOptions.endScale">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>发射速率/</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.emissionRate">
</div>
</div>
<div class="col">
<div class="row">
<span>尺寸像素</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.particleSize">
</div>
</div>
</div>
</div>
<div class="div-item" v-else>
<div class="row">
<div class="col">
<div class="row">
<span>速度</span>
<input type="range" max="30" min="0" step="0.1" v-model="entityOptions.speed">
</div>
</div>
<div class="col">
<div class="row">
<span>发射速率/</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.emissionRate">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>最小存在时间</span>
<input type="range" max="100" min="0.01" step="0.1" v-model="entityOptions.minimumParticleLife">
</div>
</div>
<div class="col">
<div class="row">
<span>最大存在时间</span>
<input type="range" max="100" min="0.01" step="0.1" v-model="entityOptions.maximumParticleLife">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>起始比例</span>
<input type="range" max="10" min="0" step="0.1" v-model="entityOptions.startScale">
</div>
</div>
<div class="col">
<div class="row">
<span>结束比例</span>
<input type="range" max="10" min="0" step="0.1" v-model="entityOptions.endScale">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>朝向</span>
<input type="range" max="360" min="0.1" step="0.1" v-model="entityOptions.heading">
</div>
</div>
<div class="col">
<div class="row">
<span>俯仰角度</span>
<input type="range" max="360" min="0.1" step="0.1" v-model="entityOptions.pitch">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="row">
<span>尺寸像素</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.particleSize">
</div>
</div>
<div class="col">
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<div style="position: absolute; left: 24px; display: flex;">
<button @click="translate"><svg class="icon-py">
<use xlink:href="#yj-icon-py"></use>
</svg>平移</button>
</div>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { inject } from "vue";
import { TreeApi } from '@/api/tree'
import { ElMessage, ElMessageBox } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
const title: any = ref('喷泉')
const baseDialog: any = ref(null);
const eventBus: any = inject("bus");
eventBus.on("openStandTextAdd", () => {
baseDialog.value?.open()
});
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const startColorRef = ref(null)
const endColorRef = ref(null)
const open = async (id: any, type: string) => {
if (type) {
if (type === 'fountain') {
title.value = '喷泉'
}
else if (type === 'smoke') {
title.value = '烟雾'
}
else if (type === 'flame') {
title.value = '火焰'
}
else if (type === 'waterL') {
title.value = '喷射水柱'
}
}
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
new window.YJColorPicker({
el: startColorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.startColor,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.startColor = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.startColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
new window.YJColorPicker({
el: endColorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.endColor,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.endColor = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.endColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const translate = () => {
if (that.positionEditing) {
that.closePositionEditing()
}
else {
that.openPositionEditing(() => {
entityOptions.value.options.lng = structuredClone(that.options.lng)
entityOptions.value.options.lat = structuredClone(that.options.lat)
entityOptions.value.options.alt = structuredClone(that.options.alt)
})
}
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
// 删除不必要的属性
delete params.host
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0,
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
close()
ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
that.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
that.reset()
eventBus?.emit("destroyComponent")
}
defineExpose({
open,
close
})
</script>
<style scoped lang="scss"></style>

View File

@ -134,7 +134,8 @@
<div class="col" style="margin: 0px;">
<span class="label">模型动画</span>
<div class="input input-select model-animate-select"></div>
<el-select class="model-animate-select" v-model="entityOptions.modelAnimate" v-if="entityOptions.model && entityOptions.model.loader && entityOptions.model.loader.components && entityOptions.model.loader.components.animations">
<el-select class="model-animate-select" v-model="entityOptions.modelAnimate"
v-if="entityOptions.model && entityOptions.model.loader && entityOptions.model.loader.components && entityOptions.model.loader.components.animations">
<el-option label="无"></el-option>
<el-option v-for="item in entityOptions.model.loader.components.animations" :label="item.name"
:value="item.name"></el-option>
@ -285,32 +286,36 @@ const close = () => {
const remove = () => {
close()
ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
that.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
that.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
}
const clickChangeModel = () => { }
const clickChangeModel = () => {
eventBus.emit('openModel', true, (url) => {
that.changeModelUrl(url)
}, 'trajectoryMotion')
}
const modelRotate = () => {
that.modelRotate()
}

View File

@ -0,0 +1,238 @@
<template>
<Dialog ref="baseDialog" title="实体墙属性" left="180px" top="100px" className="wall-stereoscopic"
:closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name">
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color" ref="colorRef"></div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">宽度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" data-min="0.01" min="0.01" max="999999"
v-model="entityOptions.width">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col">
<span class="label">拉伸高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" min="0" max="999999999"
v-model="entityOptions.extrudedHeight">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col material-box">
<span class="label">拐角类型</span>
<el-select class="input input-select input-select-line-type"
v-model="entityOptions.material">
<el-option v-for="item in material" :key="item.key" :label="item.name" :value="item.key">
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
</el-option>
</el-select>
</div>
<div class="col material-box">
<span class="label">墙体样式</span>
<el-select class="input input-select input-select-line-type"
v-model="entityOptions.material">
<template #label="{ label, value }">
<i class="yj-custom-icon" :class="material[value].icon"></i>
{{ label }}
</template>
<el-option v-for="item in material" :key="item.key" :label="item.name" :value="item.key">
<div style="display: flex; align-items: center;">
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
</div>
</el-option>
</el-select>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">墙体闭合</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail">
</div>
<div class="col">
</div>
</div>
</div>
<div class="div-item">
<div class="row">
<el-tabs v-model="activeName">
<el-tab-pane label="属性信息" name="1">
<attribute :entityOptions="entityOptions"></attribute>
</el-tab-pane>
<el-tab-pane label="标签风格" name="2">
<labelStyle :entityOptions="entityOptions"></labelStyle>
</el-tab-pane>
</el-tabs>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<div style="position: absolute; left: 24px; display: flex;">
<button @click="nodeEdit">
<svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use>
</svg>二次编辑
</button>
</div>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { inject } from "vue";
import { TreeApi } from '@/api/tree'
import { ElMessage, ElMessageBox } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
import attribute from './attribute.vue'
import labelStyle from './labelStyle.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
const baseDialog: any = ref(null);
const eventBus: any = inject("bus");
const material = ref([
{
name: '纯色墙',
value: '纯色墙',
key: 0,
icon: 'icon-wall'
},
{
name: '红砖墙',
value: '红砖墙',
key: 1,
icon: 'icon-wall-brick1'
},
{
name: '黄砖墙',
value: '黄砖墙',
key: 2,
icon: 'icon-wall-brick2'
},
{
name: '灰瓷墙',
value: '灰瓷墙',
key: 3,
icon: 'icon-wall-brick3'
}
])
eventBus.on("openStandTextAdd", () => {
baseDialog.value?.open()
});
const activeName = ref('1')
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const colorRef = ref(null)
const open = async (id: any) => {
that = window.earth.entityMap.get('aaa')
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
let colorPicker = new window.YJColorPicker({
el: colorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.color = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
// 删除不必要的属性
delete params.host
console.log('params', params)
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0,
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
close()
ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
entityOptions.value.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
}
const nodeEdit = () => {
that.nodeEdit()
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
that.reset()
eventBus?.emit("destroyComponent")
}
defineExpose({
open,
close
})
</script>
<style scoped lang="scss"></style>

View File

@ -29,11 +29,16 @@
</div>
<div class="col material-box">
<span class="label">材质样式</span>
<el-select class="input input-select input-select-line-type" style="margin-left: 20px"
v-model="entityOptions.material">
<el-select class="input input-select input-select-line-type" v-model="entityOptions.material">
<template #label="{ label, value }">
<i class="yj-custom-icon" :class="material[value].icon"></i>
{{ label }}
</template>
<el-option v-for="item in material" :key="item.key" :label="item.name" :value="item.key">
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
<div style="display: flex; align-items: center;">
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
</div>
</el-option>
</el-select>
</div>
@ -166,30 +171,30 @@ const close = () => {
const remove = () => {
close()
ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
entityOptions.value.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
.then(async () => {
let selectNodes = getSelectedNodes(window.treeObj)
let source_ids = cusRemoveNode(window.treeObj, selectNodes)
const res = await TreeApi.removeDirectory({ ids: source_ids })
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success'
})
entityOptions.value.remove()
} else {
ElMessage({
message: res.msg || '删除失败',
type: 'error'
})
}
})
.catch(() => {
// 用户点击取消,不执行任何操作
})
}
const nodeEdit = () => {
that.nodeEdit()

View File

@ -22,7 +22,7 @@
<span class="label">高度</span>
<div class="input-number input-number-unit-1">
<input class="input" type="number" title="" v-model="entityOptions.height">
<span class="unit">px</span>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>

View File

@ -66,6 +66,7 @@ export const useRightOperate = () => {
if (extension === 'mbtiles') {
params2.alpha = 1
params2.brightness = 1
params2.layerIndex = 99999
}
if (extension === 'apk') {
// params2.exaggeration = 1
@ -96,10 +97,10 @@ export const useRightOperate = () => {
let detail = JSON.parse(res.data.detail)
let mapParams = { ...detail, ...res.data.params }
await initMapData(res.data.sourceType, mapParams, (entity)=>{
await initMapData(res.data.sourceType, mapParams, (entity) => {
entity.flyTo()
})
if(res.data.sourceType) {}
if (res.data.sourceType) { }
res.data.params = JSON.stringify(res.data.params)
res.data.detail = JSON.stringify(res.data.detail)
cusAddNodes(window.treeObj, params.parentId, [res.data])
@ -312,13 +313,21 @@ export const useRightOperate = () => {
}
}
//提升图层
const layerRaise = () => { }
const layerRaise = () => {
layerIndex("layerRaise");
}
//降低图层
const layerLower = () => { }
const layerLower = () => {
layerIndex("layerLower");
}
//置顶图层
const layerToTop = () => { }
const layerToTop = () => {
layerIndex("layerToTop");
}
//置底图层
const layerToBottom = () => { }
const layerToBottom = () => {
layerIndex("layerToBottom");
}
//切片
const tilesetClipping = () => { }
const rightMenus: any = reactive({
@ -412,6 +421,56 @@ export const useRightOperate = () => {
}
})
const layerIndex = (key) => {
let selectNodes = getSelectedNodes(window.treeObj);
if (selectNodes && selectNodes[selectNodes.length - 1]) {
let node = selectNodes[selectNodes.length - 1]
let layer = window.earth.entityMap.get(node.id);
layer[key]();
_updateLayerIndex();
}
}
const _updateLayerIndex = () => {
let nodes = window.treeObj.transformToArray(
window.treeObj.getNodes()
);
let layers:any = [];
let arr = [
"ArcgisWXImagery",
"ArcgisBLUEImagery",
"ArcgisLWImagery",
"GDLWImagery",
"GDWXImagery",
"GDSLImagery",
"layer",
];
nodes.forEach((item) => {
if (arr.includes(item.sourceType) && item.isShow) {
let entityOptions = window.earth.entityMap.get(item.id)
let layerIndex = entityOptions.layerIndex;
layers.push({ id: item.id, layerIndex });
let params = {
layerIndex: entityOptions.layerIndex,
alpha: entityOptions.alpha,
brightness: entityOptions.brightness,
name: entityOptions.name,
show: entityOptions.show,
id: item.id,
}
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
});
console.log('layers', layers)
}
// 图片文件上传后续
async function handleFileImgInput(files: any, parentId: string, type: string) {
const { ipcRenderer } = require('electron')

View File

@ -97,16 +97,16 @@ export const useTree = () => {
const someNode: any = getSameLevel(window.treeObj, treeNodes[0])
const newNode = someNode.map((item: any) => {
let index = item.getIndex()
item.tree_index = index
item.treeIndex = index
return {
...item,
tree_index: item.getIndex()
treeIndex: item.getIndex()+1
}
})
const list = newNode.map((item: any) => {
return {
id: item.id,
tree_index: item.tree_index,
treeIndex: item.treeIndex,
parentId: item.parentId
}
})
@ -500,6 +500,8 @@ export const useTree = () => {
(window as any).pressModelMap.set(res.data[i].id + "_" + obj.modelId, res.data[i]);
}
res.data[i].icon = await cusNodeIcon(res.data[i]);
res.data[i].class = 'xxxx'
res.data[i].className = 'xxxx'
}
}
zNodes.value = res.data
@ -533,6 +535,16 @@ export const useTree = () => {
}
const initTreeCallBack = () => {
let arr = [
"ArcgisWXImagery",
"ArcgisBLUEImagery",
"ArcgisLWImagery",
"GDLWImagery",
"GDWXImagery",
"GDSLImagery",
"layer",
];
let layers:any = []
if (window.earth) {
for (let i = 0; i < zNodes.value.length; i++) {
if (zNodes.value[i].sourceType === 'directory') {
@ -548,7 +560,23 @@ export const useTree = () => {
if (!params.name) {
params.name = zNodes.value[i].sourceName
}
initMapData(zNodes.value[i].sourceType, { ...detail, ...params }, null)
if(arr.includes(zNodes.value[i].sourceType)) {
layers.push(
{
sourceType: zNodes.value[i].sourceType,
params: { ...detail, ...params }
}
)
}
else {
initMapData(zNodes.value[i].sourceType, { ...detail, ...params }, null)
}
}
layers.sort((obj1, obj2) => {
return obj1.params.layerIndex - obj2.params.layerIndex;
});
for(let i = 0; i < layers.length; i++) {
initMapData(layers[i].sourceType, layers[i].params, null)
}
}
}

View File

@ -34,6 +34,13 @@ export const useTreeNode = () => {
// detailFun: get_detail_line,
// allowChildren: false,
},
polyhedronObject: {
rightMenus: ['edit', 'del', 'setView', 'resetView']
// render: renderBaseMarker,
// render2d: renderBaseMarker2d,
// detailFun: get_detail_line,
// allowChildren: false,
},
curve: {
rightMenus: ['edit', 'del', 'setView', 'resetView']
// render: renderCurve,
@ -94,7 +101,7 @@ export const useTreeNode = () => {
// detailFun: get_detail_groundImage,
// allowChildren: false,
},
waterl: {
waterL: {
rightMenus: ['edit', 'del', 'setView', 'resetView']
// render: renderSpout,
// detailFun: get_detail_waterl,
@ -313,7 +320,7 @@ export const useTreeNode = () => {
},
fountain: {
// render: renderFountain,
rightMenus: ['edit', 'del'],
rightMenus: ['edit', 'del', 'setView', 'resetView'],
// detailFun: get_detail_fountain,
allowChildren: false
},
@ -387,9 +394,9 @@ export const useTreeNode = () => {
flyLine: {
rightMenus: [
'edit',
'del'
// "setView",
// "resetView" /*"setView", "resetView"*/,
'del',
'setView',
'resetView'
]
// render: renderFlyLine,
// detailFun: get_detail_flyLine,
@ -583,22 +590,25 @@ export const useTreeNode = () => {
left: x + 'px',
visibility: 'visible'
})
if (
Object.prototype.toString.call(selectedNodes) === '[object Array]' &&
selectedNodes.length > 1
) {
arr = ['del']
} else {
if (selectedNodes.length == 0) arr = ['addDirectory']
else {
try {
arr = nodeType[selectedNodes[0].sourceType].rightMenus
} catch (e) {
console.log('e', e)
arr = []
if ((window as any).checkAuthIsValid) {
if (
Object.prototype.toString.call(selectedNodes) === '[object Array]' &&
selectedNodes.length > 1
) {
arr = ['del']
} else {
if (selectedNodes.length == 0) arr = ['addDirectory']
else {
try {
arr = nodeType[selectedNodes[0].sourceType].rightMenus
} catch (e) {
console.log('e', e)
arr = []
}
}
}
}
return arr
}

View File

@ -10,14 +10,8 @@
<firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
<!--底部菜单-->
<bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
<input
type="file"
id="fileInputlink"
style="display: none"
multiple
accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile"
/>
<input type="file" id="fileInputlink" style="display: none" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile" />
<!-- 多点视线分析 -->
<Visibility ref="visibility"></Visibility>
@ -88,6 +82,7 @@ import tileset from '../components/propertyBox/tileset.vue'
import layer from '../components/propertyBox/layer.vue'
import trajectoryMotion from '../components/propertyBox/trajectoryMotion.vue'
import wallStereoscopic from '../components/propertyBox/wallStereoscopic.vue'
import wallRealStereoscopic from '../components/propertyBox/wallRealStereoscopic.vue'
import circleDiffuse from '../components/propertyBox/circleDiffuse.vue'
import radarScan from '../components/propertyBox/radarScan.vue'
import radarScanStereoscopic from '../components/propertyBox/radarScanStereoscopic.vue'
@ -107,6 +102,11 @@ import waterSurface from '../components/propertyBox/waterSurface.vue'
import { addMapSource } from '../../common/addMapSource'
import modelSetting from '../components/propertyBox/modelSetting.vue'
import modelObject from '../components/propertyBox/modelObject.vue'
import particleEffects from '../components/propertyBox/particleEffects.vue'
import flyLine from '../components/propertyBox/flyLine.vue'
import explosion from '../components/propertyBox/explosion.vue'
import { GisApi } from '@/api/gisApi'
@ -217,6 +217,11 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
await nextTick()
dynamicComponentRef.value?.open(id)
break
case 'entityWall':
currentComponent.value = wallRealStereoscopic
await nextTick()
dynamicComponentRef.value?.open(id)
break
case 'diffuseScan':
currentComponent.value = circleDiffuse
await nextTick()
@ -249,6 +254,24 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
await nextTick()
dynamicComponentRef.value?.open(id)
break
case 'fountain':
case 'fire':
case 'smoke':
case 'waterL':
currentComponent.value = particleEffects
await nextTick()
dynamicComponentRef.value?.open(id, sourceType)
break
case 'flyLine':
currentComponent.value = flyLine
await nextTick()
dynamicComponentRef.value?.open(id)
break
case 'explosion':
currentComponent.value = explosion
await nextTick()
dynamicComponentRef.value?.open(id)
break
default:
break
}
@ -296,17 +319,17 @@ const createEarth = async () => {
YJ.Global.rotateAround(window.earth, object.position)
break
case 'textBox':
// let id = new YJ.Tools().randomString()
// let name = '文本框'
// addMapSource({
// type: 'textBox',
// id: id,
// sourceName: name,
// opt: {
// id: id,
// position: object.position
// }
// })
let id = new YJ.Tools().randomString()
let name = '文本框'
addMapSource({
type: 'textBox',
id: id,
sourceName: name,
opt: {
id: id,
position: object.position
}
})
break
case 'attribute':
let node = window.treeObj.getNodeByParam('id', object.id, null)
@ -372,9 +395,9 @@ const getStatus = (time) => {
const currentTimestamp = Date.now()
if (timestamp > currentTimestamp) {
;(window as any).checkAuthIsValid = true
; (window as any).checkAuthIsValid = true
} else {
;(window as any).checkAuthIsValid = false
; (window as any).checkAuthIsValid = false
}
}