提交
BIN
ffplay/20250917204504.mp4
Normal file
BIN
resources/java/app/upload/033b9092110c478797b9b1cdb9b40de3.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/08f0721a0d8e48ae83b8de6e8b6c1e75.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
resources/java/app/upload/0c67c2ad328042ea948dc48ec03b3f57.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/100161d302f44a659f3abfc0adb0038c.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
resources/java/app/upload/1062975692f646a6982a367e8f13935f.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/12c436c4cad549b1b38eff2568550ee1.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/18bcbb8043094c4181e8744ae7a84de9.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/1e08f64aa77d404bb3f1de555dc6a0ac.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/257fff4cff71496db00e40fef3487ac4.jpg
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
resources/java/app/upload/2c8f6ff66541480e93361a73708c16e2.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/2dded9e561a742f88d3a04ad11540053.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/330d8f72f895485290d0b408fa707f81.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/3baf5da7c6154a8c8ff0b2cbb919451f.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/3fc40e256c7f4cefa3cc5cca84d20d2b.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/41ade62b36904aa1b77b6ae450cd08b2.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/474d50b295b043aea8b71c09ecfc3fe6.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/478fb67eaa91490fbe6cdc488f7415bf.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
resources/java/app/upload/4b59dad7d85c4da0b57dc6e3e44de559.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/4baa689f69c34736b601f52a9362e4c7.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/532778a977564f62a0f2d83a998a9fc4.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/5da68b3196b046a494888c122c8f1978.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/61fd16a0bb1b46d6a2aaf7e1c877547d.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/691cbca45f2b40ac92194a0f4a3c8512.jpg
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
resources/java/app/upload/6c9a4dded45443208d6351863643648b.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/6f4b0752eca94b60911ebc13c0d020cf.JPG
Normal file
|
After Width: | Height: | Size: 7.1 MiB |
BIN
resources/java/app/upload/702b03455ae24f4aaa04cbaed17d6c29.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
resources/java/app/upload/71b4ddc5ac6745c489478a6274ab7321.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/720df0f8ca5743dd9c9babb5e22c4f54.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/75d897267dc9491d8255b498dd44edfb.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/7631415789d7434f9638a385a11b0dbf.JPG
Normal file
|
After Width: | Height: | Size: 6.7 MiB |
BIN
resources/java/app/upload/80a9b3701a25480b9c731db92501015a.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/8286f6b52f254884af601447ca13a1d5.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/8e515835140c4128b0ae4451e18dde81.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/8ea517aa085f4979a6edafe754a4dbe6.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/907bc53ebfd04f9b9c6212b22a533b86.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/a6be98ea6a2d47ecad60786f1a2e1751.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/ab5d72cbcf0b45e580588e74f92b592a.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/ad823c4046704e1c84eb37797d1d844b.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/afbad7b36e784bcdaf8ce099022ada48.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
resources/java/app/upload/b1ffe201bf2e4438b0644573c89e61c8.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/b22ecf1de04348c687ab284a64b02696.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/b7d8a392f4ae448f9e6ea5d8d53c7960.jpg
Normal file
|
After Width: | Height: | Size: 5.4 MiB |
BIN
resources/java/app/upload/ba5a9fe7d09f4b63b4fde841dff4c48e.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/bfba71b1d9834395a9f78d8139414c75.jpg
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
resources/java/app/upload/c22545152fe947f5be5e90644eee4947.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/c977d56bc876462aabe4e65787f26772.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/cfa5bd609fea44e28d0e8c46950612cc.JPG
Normal file
|
After Width: | Height: | Size: 6.9 MiB |
BIN
resources/java/app/upload/d2889ca0ad30448a9d4157bf7b4709b7.JPG
Normal file
|
After Width: | Height: | Size: 6.8 MiB |
BIN
resources/java/app/upload/d7b05fc0252841049e0dd75e877e86fa.jpg
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
resources/java/app/upload/d9d820f53cc241db80fc2be0a1fabcd7.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
BIN
resources/java/app/upload/e093ba97f3884e6ab10c8748201d2aef.jpg
Normal file
|
After Width: | Height: | Size: 5.0 MiB |
BIN
resources/java/app/upload/f6cbc3ded9f14158a9bc6d6d84a82e76.JPG
Normal file
|
After Width: | Height: | Size: 7.0 MiB |
@ -136,9 +136,9 @@ function createWindow(): void {
|
||||
ipcMain.on("open-directory-dialog", (event, option) => {
|
||||
// @ts-ignore
|
||||
dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
||||
properties: option.properties,
|
||||
filters: option.filters,
|
||||
})
|
||||
properties: option.properties,
|
||||
filters: option.filters,
|
||||
})
|
||||
.then((files) => {
|
||||
let arr = [];
|
||||
if (!files.canceled) {
|
||||
@ -194,6 +194,20 @@ function createWindow(): void {
|
||||
}
|
||||
});
|
||||
});
|
||||
// 监听渲染进程创建新窗口的请求
|
||||
ipcMain.handle('create-new-window', async (event, params, url, option) => {
|
||||
try {
|
||||
const newWindow = await new BrowserWindow(params)
|
||||
if (url) {
|
||||
await newWindow.loadURL(url)
|
||||
await newWindow.webContents.send("data", option)
|
||||
}
|
||||
return newWindow.id
|
||||
} catch (error) {
|
||||
console.error('创建窗口失败:', error);
|
||||
throw error; // 抛出错误以便渲染进程捕获
|
||||
}
|
||||
})
|
||||
// 设置窗口标题和图标
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url)
|
||||
|
||||
1
src/renderer/components.d.ts
vendored
@ -12,6 +12,7 @@ declare module 'vue' {
|
||||
Directory: typeof import('./src/components/dialog/directory.vue')['default']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
|
||||
ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
|
||||
15676
src/renderer/public/Vue/index.css
Normal file
1
src/renderer/public/Vue/index.js
Normal file
12014
src/renderer/public/Vue/vue.js
Normal file
169
src/renderer/public/Vue/w-e-text.css
Normal file
@ -0,0 +1,169 @@
|
||||
.w-e-text-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-e-text-container .w-e-progress {
|
||||
position: absolute;
|
||||
background-color: #1e88e5;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.w-e-text-container .placeholder {
|
||||
color: #d4d4d4;
|
||||
position: absolute;
|
||||
font-size: 11pt;
|
||||
line-height: 22px;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.w-e-text {
|
||||
padding: 0 10px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.w-e-text p,
|
||||
.w-e-text h1,
|
||||
.w-e-text h2,
|
||||
.w-e-text h3,
|
||||
.w-e-text h4,
|
||||
.w-e-text h5,
|
||||
.w-e-text table,
|
||||
.w-e-text pre {
|
||||
margin: 10px 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.w-e-text ul,
|
||||
.w-e-text ol {
|
||||
margin: 10px 0 10px 20px;
|
||||
}
|
||||
|
||||
.w-e-text blockquote {
|
||||
display: block;
|
||||
border-left: 8px solid #d0e5f2;
|
||||
padding: 5px 10px;
|
||||
margin: 10px 0;
|
||||
line-height: 1.4;
|
||||
font-size: 100%;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.w-e-text code {
|
||||
display: inline-block;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
padding: 3px 5px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
.w-e-text pre code {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.w-e-text table {
|
||||
border-top: 1px solid #ccc;
|
||||
border-left: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.w-e-text table td,
|
||||
.w-e-text table th {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
padding: 3px 5px;
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.w-e-text table th {
|
||||
border-bottom: 2px solid #ccc;
|
||||
text-align: center;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
||||
.w-e-text:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.w-e-text img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.w-e-text img:hover {
|
||||
box-shadow: 0 0 5px #333;
|
||||
}
|
||||
|
||||
.w-e-text .w-e-todo {
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.w-e-text .w-e-todo li {
|
||||
list-style: none;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.w-e-text .w-e-todo li span:nth-child(1) {
|
||||
position: relative;
|
||||
left: -18px;
|
||||
}
|
||||
|
||||
.w-e-text .w-e-todo li span:nth-child(1) input {
|
||||
position: absolute;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.w-e-text .w-e-todo li span:nth-child(1) input[type="checkbox"] {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
|
||||
.w-e-tooltip {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
color: #f1f1f1;
|
||||
background-color: rgba(0, 0, 0, 0.75);
|
||||
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
|
||||
border-radius: 4px;
|
||||
padding: 4px 5px 6px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.w-e-tooltip-up::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border: 5px solid rgba(0, 0, 0, 0);
|
||||
border-top-color: rgba(0, 0, 0, 0.73);
|
||||
}
|
||||
|
||||
.w-e-tooltip-down::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border: 5px solid rgba(0, 0, 0, 0);
|
||||
border-bottom-color: rgba(0, 0, 0, 0.73);
|
||||
}
|
||||
|
||||
.w-e-tooltip-item-wrapper {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.w-e-tooltip-item-wrapper:hover {
|
||||
color: #ccc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
453
src/renderer/public/infoShow.html
Normal file
@ -0,0 +1,453 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="./Vue/index.css">
|
||||
<link rel="stylesheet" href="./Vue/w-e-text.css">
|
||||
<script src="./Vue/vue.js"></script>
|
||||
<script src="./Vue/index.js"></script>
|
||||
<link href="./viewerJs/dist/viewer.css" rel="stylesheet">
|
||||
<script src="./viewerJs/dist/viewer.js"></script>
|
||||
<style>
|
||||
body,
|
||||
#info,
|
||||
div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#info {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* height: 100vh; background-color: rgba(255, 255, 255, 0.014); */
|
||||
/*color: red;*/
|
||||
}
|
||||
|
||||
.tabs-header {
|
||||
display: flex;
|
||||
background: #ccc;
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
overflow-x: scroll;
|
||||
/* height: 41px; */
|
||||
}
|
||||
|
||||
.tabs-header::-webkit-scrollbar {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.tabs-header::-webkit-scrollbar-thumb {
|
||||
background: #f0f0f0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tabs-header::-webkit-scrollbar-track {
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tabs-header>.item {
|
||||
border-radius: 6px;
|
||||
/* padding: 5px 15px; */
|
||||
padding: 5px 0 5px 0;
|
||||
margin: 5px 3px;
|
||||
min-width: 80px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
/* 合并边框 */
|
||||
width: 100%;
|
||||
/* 表格宽度 */
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<style type="text/css">
|
||||
#iframe1>[src] {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="info">
|
||||
<!-- zhgeli -->
|
||||
<div class="tabs-header">
|
||||
<template v-for="(item,index) in tabsData">
|
||||
<div :class="['item',index!=tabsData.length-1?'borderRight':'',index==activeIndex?'active':'',]"
|
||||
@click="clickItem(item,index)">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 全景图片 -->
|
||||
<template v-if="activeItem.type === '全景图'">
|
||||
<div style="flex: 9" id="vrBox"></div>
|
||||
</template>
|
||||
<template v-else-if="activeItem.name === '富文本'">
|
||||
<div style="flex: 9" class="w-e-text" v-html="info.text"></div>
|
||||
</template>
|
||||
<template v-else-if="activeItem.type === '物资'">
|
||||
<div v-if="activeItem.type === '物资'" style="flex: 9" class="w-e-text">
|
||||
<table id="myTable" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>名称</th>
|
||||
<th>数量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="isPicture">
|
||||
<div style="flex: auto;">
|
||||
<img v-if="isSvg" style="width: 100%;height: 100%" :src="activeItem.url" alt="">
|
||||
<iframe v-else style="width: 100%;height: 100%" src="./showPicture.html" frameborder="0"
|
||||
id="iframe1"></iframe>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div style="flex: auto;">
|
||||
<iframe style="width: 100%;height: 100%" :src="activeItem.url" frameborder="0" id="iframe2">
|
||||
</iframe>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
const fs = require('fs')
|
||||
//调用子页面方法
|
||||
function getIframe(data, str) {
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = "./vrHtml/index.html";
|
||||
iframe.style.width = "100%"
|
||||
iframe.style.height = "100%"
|
||||
iframe.setAttribute('frameborder', 0)
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow.setIframe(data, str);
|
||||
}
|
||||
document.getElementById('vrBox').appendChild(iframe);
|
||||
}
|
||||
//获取img元素并且插入属性
|
||||
function getImg(data) {
|
||||
console.log('进入方法', data);
|
||||
|
||||
let iframe1 = document.getElementById('iframe1')
|
||||
|
||||
console.log(iframe1);
|
||||
|
||||
if (!iframe1) {
|
||||
return
|
||||
}
|
||||
console.log('url', data);
|
||||
|
||||
iframe1.contentWindow.postMessage(data, '*')
|
||||
console.log('urlurlurlurlurl', data);
|
||||
// let frame = window.frames['iframeDialog']
|
||||
iframe1.onload = () => {
|
||||
iframe1.contentWindow.postMessage(data, '*')
|
||||
}
|
||||
}
|
||||
|
||||
//调用子组件关闭按钮
|
||||
function closeImg() {
|
||||
let iframe1 = document.getElementById('iframe1')
|
||||
if (!iframe1) {
|
||||
return
|
||||
}
|
||||
iframe1.contentWindow.close()
|
||||
}
|
||||
function closeVr() {
|
||||
let parentElement = document.getElementById('vrBox')
|
||||
if (!parentElement) {
|
||||
return
|
||||
}
|
||||
removeAllChildren(parentElement);
|
||||
}
|
||||
function removeAllChildren(parentNode) {
|
||||
while (parentNode.firstChild) {
|
||||
parentNode.removeChild(parentNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<script>
|
||||
const ipcRenderer = require('electron').ipcRenderer
|
||||
new Vue({
|
||||
el: '#info',
|
||||
data: function () {
|
||||
return {
|
||||
showRichText: '',
|
||||
activeIndex: 0,
|
||||
activeItem: {},
|
||||
tabsData: [],
|
||||
info: {
|
||||
type: "",
|
||||
text: "",
|
||||
hrefs: "",
|
||||
vrPath: '',
|
||||
},
|
||||
isPicture: false,
|
||||
tbody: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
activeItem: {
|
||||
handler: function (val, oldVal) {
|
||||
this.appendData(val)
|
||||
console.log('document.getElementByIdmyObject', document.getElementById('myObject'));
|
||||
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 填入数据
|
||||
appendData(item) {
|
||||
if (item.name === '物资') {
|
||||
this.$nextTick(() => {
|
||||
const table = document.querySelector('#myTable');
|
||||
if (table) {
|
||||
table.appendChild(this.tbody)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
clickItem(item, i) {
|
||||
if (this.tabsData.length < 1) {
|
||||
console.log('只有一个选项,不允许切换');
|
||||
return;
|
||||
}
|
||||
let setName = () => {
|
||||
this.showRichText = item.name
|
||||
this.activeIndex = i
|
||||
this.activeItem = item
|
||||
closeImg()
|
||||
console.log('this.activeItem', this.activeItem);
|
||||
this.renderImgView()
|
||||
this.$nextTick(() => {
|
||||
if (this.activeItem.name.indexOf('ISC-') > -1) {
|
||||
if (!this.player) {
|
||||
this.player = new window.JSPlugin({
|
||||
szId: 'player',
|
||||
szBasePath: "./sdk",
|
||||
iMaxSplit: 1,
|
||||
iCurrentSplit: 1,
|
||||
openDebug: true,
|
||||
oStyle: {
|
||||
borderSelect: IS_MOVE_DEVICE ? '#000' : '#FFCC00',
|
||||
}
|
||||
})
|
||||
}
|
||||
//播放某一特定监控
|
||||
let playURL = this.activeItem.previewUrl, index = this.player.currentWindowIndex, mode = 0//:0=普通模式; 1=高级模式
|
||||
|
||||
this.player.JS_Play(playURL, { playURL, mode }, index).then(
|
||||
() => { console.log('realplay success') },
|
||||
e => { console.error(e) }
|
||||
)
|
||||
|
||||
console.log("this.player", this.player);
|
||||
|
||||
}
|
||||
})
|
||||
closeVr()
|
||||
// setIframe2()
|
||||
}
|
||||
if (['富文本', '全景图', '链接'].includes(this.activeItem.type)) {
|
||||
setName()
|
||||
this.$nextTick(() => {
|
||||
getImg(this.activeItem.url)
|
||||
})
|
||||
return
|
||||
}
|
||||
setName()
|
||||
},
|
||||
renderImgView() {
|
||||
console.log(this.activeItem.url);
|
||||
let name
|
||||
if (this.activeItem.url) {
|
||||
name = this.activeItem.url.slice(this.activeItem.url.length - 3, this.activeItem.url.length)
|
||||
}
|
||||
console.log('node.detail.namenode.detail.namenode.detail.name', name);
|
||||
this.isPicture = ['jpg', 'png', 'JPG', 'PNG', 'JPEG', 'jpeg', 'gif', 'webp', 'GIF', 'bmp'].includes(name)
|
||||
console.log('this.isPicture', this.isPicture);
|
||||
this.isSvg = (name === 'svg');
|
||||
setTimeout(() => {
|
||||
//我希望图片和全景都有时,他们各自渲染各自的
|
||||
if (this.activeItem.type === '全景图') {
|
||||
getIframe(this.activeItem.url, '')
|
||||
} else {
|
||||
getImg(this.activeItem.url)
|
||||
}
|
||||
// if (!Boolean(this.info.panorama.length)) {
|
||||
// console.log('图片渲染', 1232132);
|
||||
// getImg(this.activeItem.url)
|
||||
// } else {
|
||||
// getIframe(this.activeItem.url, '')
|
||||
// }
|
||||
}, 0)
|
||||
},
|
||||
|
||||
},
|
||||
mounted() {
|
||||
window.ssssssssssssss = this.tabsData
|
||||
let fs = require('fs')
|
||||
console.log('fsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfs', fs);
|
||||
ipcRenderer.on('data', (event, obj) => {
|
||||
this.info = obj.info
|
||||
console.log('ddddddddddddddddddddddddddd', this.info);
|
||||
document.title = obj.source_name
|
||||
let arr = this.info.hrefs
|
||||
arr.forEach(item => {
|
||||
console.log(fs.existsSync(item.url));
|
||||
if (fs.existsSync(item.url)) {
|
||||
let url = ""
|
||||
if (item.url.startsWith("http"))
|
||||
url = item.url
|
||||
else {
|
||||
//说明是本地的json,在磁盘中存在的
|
||||
if (item.url.includes(":")) {
|
||||
url = obj.host + "/fileInfo/previewLocal?fileAbsolutePath=" + encodeURIComponent(item.url)
|
||||
} else {
|
||||
if (obj.host) {
|
||||
let o = new URL(object.url, obj.host)
|
||||
url = o.href
|
||||
} else
|
||||
url = item.url
|
||||
}
|
||||
}
|
||||
item.url = url
|
||||
} else {
|
||||
if (!item.url.startsWith('http')) {
|
||||
// item.url = this.info.env + "/" + item.url
|
||||
item.url = obj.host + item.url
|
||||
}
|
||||
}
|
||||
})
|
||||
this.tabsData = arr
|
||||
console.log('this.tabsData', this.tabsData);
|
||||
let hasRichText = Boolean(this.info.text)
|
||||
let hasVrPath = Boolean(this.info.vrPath)
|
||||
let hasVr = Boolean(this.info.vr.length)
|
||||
let hasGoods = Boolean(this.info.goods.length)
|
||||
let hasISC = this.info.ISC && Boolean(this.info.ISC.length > 0)
|
||||
|
||||
if (hasRichText) {
|
||||
this.tabsData.unshift({ name: "富文本", type: '富文本', href: this.info.text })
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
}
|
||||
// 当hasRichText为false,将第一个选项设置为链接
|
||||
if (!hasRichText && !hasVrPath && !hasVr && !hasGoods && !hasISC) {
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
this.activeItem.type = '链接'
|
||||
this.clickItem(this.activeItem, this.activeIndex)
|
||||
}
|
||||
if (this.info.type == "link" && this.tabsData.length > 0) {
|
||||
this.activeIndex = hasRichText ? 0 : 0
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
this.showRichText = ''
|
||||
this.activeItem.type = '链接'
|
||||
this.clickItem(this.activeItem, this.activeIndex)
|
||||
}
|
||||
// let jsonPath = obj.info.source_path.replace('.jpg', '.json')
|
||||
// console.log(hasRichText, hasVrPath, fs.existsSync(jsonPath), this.tabsData);
|
||||
let str = ""
|
||||
// fetch(jsonPath)
|
||||
// if (fs.existsSync(jsonPath)) {
|
||||
// str = String(fs.readFileSync(jsonPath))
|
||||
// }
|
||||
/*else {
|
||||
return
|
||||
}*/
|
||||
if (hasVrPath) {
|
||||
this.tabsData.unshift({ name: "全景图", type: '全景图', href: this.info.vrPath })
|
||||
this.$nextTick(() => {
|
||||
getIframe(this.info.vrPath, str)
|
||||
})
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
}
|
||||
if (hasISC) {
|
||||
this.info.ISC.forEach(item => {
|
||||
this.tabsData.push({ name: "ISC-" + item.name, cameraIndexCode: item.cameraIndexCode, status: item.status })
|
||||
})
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
}
|
||||
if (hasGoods) {
|
||||
this.tabsData.unshift({ name: "物资", type: '物资' })
|
||||
// tbody.appendChild(row);
|
||||
this.tbody = document.createElement('tbody')
|
||||
|
||||
this.info.goods.reverse().forEach((item, index) => {
|
||||
const row = document.createElement('tr');
|
||||
row.innerHTML = `
|
||||
<td>${index + 1}</td>
|
||||
<td>${item.name}</td>
|
||||
<td>${item.cnt}</td>
|
||||
`;
|
||||
this.tbody.appendChild(row);
|
||||
});
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
}
|
||||
if (hasVr) {
|
||||
this.info.vr.forEach(item => {
|
||||
if (fs.existsSync(item.url)) {
|
||||
let url = ""
|
||||
if (item.url.startsWith("http"))
|
||||
url = item.url
|
||||
else {
|
||||
//说明是本地的json,在磁盘中存在的
|
||||
if (item.url.includes(":")) {
|
||||
url = obj.host + "/fileInfo/previewLocal?fileAbsolutePath=" + encodeURIComponent(item.url)
|
||||
} else {
|
||||
if (obj.host) {
|
||||
let o = new URL(object.url, obj.host)
|
||||
url = o.href
|
||||
} else
|
||||
url = item.url
|
||||
}
|
||||
}
|
||||
item.url = url
|
||||
} else {
|
||||
if (!item.url.startsWith('http')) {
|
||||
// item.url = this.info.env + "/" + item.url
|
||||
item.url = obj.host + item.url
|
||||
}
|
||||
}
|
||||
this.tabsData.unshift({ name: "全景图", type: '全景图', url: item.url })
|
||||
})
|
||||
this.activeItem = this.tabsData[this.activeIndex]
|
||||
this.renderImgView()
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
</script>
|
||||
|
||||
</html>
|
||||
94
src/renderer/public/showPicture.html
Normal file
@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="./Vue/index.css">
|
||||
<link rel="stylesheet" href="./Vue/w-e-text.css">
|
||||
<script src="./Vue/vue.js"></script>
|
||||
<script src="./Vue/index.js"></script>
|
||||
<link href="./viewerJs/dist/viewer.css" rel="stylesheet">
|
||||
<script src="./viewerJs/dist/viewer.js"></script>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="pictureHtml" style="width: 100%;height: 100%;">
|
||||
<img :src="url" id="imgShow" :alt="url" title="图片预览">
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
let viewer = null
|
||||
function close() {
|
||||
console.log('图片关闭被调用了', viewer);
|
||||
viewer.destroy()
|
||||
}
|
||||
new Vue({
|
||||
el: '#pictureHtml',
|
||||
data() {
|
||||
return {
|
||||
url: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setImgTools() {
|
||||
console.log('重新渲染', 123);
|
||||
let img = document.getElementById('imgShow')
|
||||
if (!img) {
|
||||
return
|
||||
}
|
||||
img.onload = () => {
|
||||
viewer = new Viewer(img, {
|
||||
toolbar: {
|
||||
zoomIn: 4,
|
||||
zoomOut: 4,
|
||||
oneToOne: false,
|
||||
reset: false,
|
||||
prev: false,
|
||||
play: {
|
||||
show: 4,
|
||||
size: 'large',
|
||||
},
|
||||
next: false,
|
||||
rotateLeft: false,
|
||||
rotateRight: false,
|
||||
flipHorizontal: 4,
|
||||
flipVertical: 4,
|
||||
},
|
||||
zoomRatio: 0.5
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('message', (data) => {
|
||||
this.url = data.data
|
||||
console.error('图片地址', this.url);
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.setImgTools()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
539
src/renderer/public/vrHtml/@photo-sphere-viewer/core/index.css
Normal file
@ -0,0 +1,539 @@
|
||||
/*!
|
||||
* PhotoSphereViewer 5.7.3
|
||||
* @copyright 2014-2015 Jérémy Heleine
|
||||
* @copyright 2024 Damien "Mistic" Sorel
|
||||
* @licence MIT (https://opensource.org/licenses/MIT)
|
||||
*/
|
||||
/* src/styles/index.scss */
|
||||
.psv-container {
|
||||
--psv-core-loaded: true;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
background: radial-gradient(#fff 0%, #fdfdfd 16%, #fbfbfb 33%, #f8f8f8 49%, #efefef 66%, #dfdfdf 82%, #bfbfbf 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
.psv-container * {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.psv-canvas-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
transition: opacity linear 100ms;
|
||||
}
|
||||
.psv-canvas {
|
||||
display: block;
|
||||
}
|
||||
.psv-loader-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 80;
|
||||
}
|
||||
.psv-loader {
|
||||
--psv-loader-border: 3px;
|
||||
--psv-loader-tickness: 10px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.psv-loader-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: rgba(61, 61, 61, 0.5);
|
||||
z-index: -1;
|
||||
}
|
||||
.psv-loader-text {
|
||||
font: 600 16px sans-serif;
|
||||
}
|
||||
.psv-navbar {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
z-index: 90;
|
||||
bottom: -40px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: rgba(61, 61, 61, 0.5);
|
||||
transition: bottom ease-in-out 0.1s;
|
||||
font: 16px sans-serif;
|
||||
cursor: default;
|
||||
}
|
||||
.psv-navbar--open {
|
||||
bottom: 0;
|
||||
}
|
||||
.psv-navbar,
|
||||
.psv-navbar * {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
.psv-button {
|
||||
flex: 0 0 auto;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background: transparent;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.psv-button--active {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.psv-button--disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.psv-button-svg {
|
||||
width: 100%;
|
||||
transform: scale(1);
|
||||
transition: transform 200ms ease;
|
||||
vertical-align: initial;
|
||||
}
|
||||
.psv-button:not(.psv-button--disabled):focus-visible {
|
||||
outline: 2px solid #007cff;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.psv-container:not(.psv--is-touch) .psv-button--hover-scale:not(.psv-button--disabled):hover .psv-button-svg {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
.psv-move-button + .psv-move-button {
|
||||
margin-left: -10px;
|
||||
}
|
||||
.psv-custom-button {
|
||||
width: auto;
|
||||
min-width: 20px;
|
||||
}
|
||||
.psv-custom-button--no-padding {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.psv-caption {
|
||||
flex: 1 1 100%;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
cursor: unset;
|
||||
padding: unset;
|
||||
height: unset;
|
||||
width: unset;
|
||||
}
|
||||
.psv-caption-content {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.psv-zoom-range.psv-button {
|
||||
width: 80px;
|
||||
height: 1px;
|
||||
margin: 10px 0;
|
||||
padding: 9.5px 0;
|
||||
max-width: 600px;
|
||||
}
|
||||
.psv-zoom-range-line {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 1px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.psv-zoom-range-handle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
top: -3px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
transform: scale(1);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.psv-zoom-range:not(.psv-button--disabled):hover .psv-zoom-range-line {
|
||||
box-shadow: 0 0 2px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.psv-zoom-range:not(.psv-button--disabled):hover .psv-zoom-range-handle {
|
||||
transform: scale(1.3);
|
||||
}
|
||||
.psv-notification {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
bottom: -40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
padding: 0 2em;
|
||||
opacity: 0;
|
||||
transition-property: opacity, bottom;
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
.psv-notification-content {
|
||||
max-width: 50em;
|
||||
background: rgba(61, 61, 61, 0.8);
|
||||
border-radius: 4px;
|
||||
padding: 0.5em 1em;
|
||||
font: 14px sans-serif;
|
||||
color: rgb(255, 255, 255);
|
||||
}
|
||||
.psv-notification--visible {
|
||||
opacity: 100;
|
||||
bottom: 80px;
|
||||
}
|
||||
.psv-overlay {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
z-index: 110;
|
||||
inset: 0;
|
||||
background: radial-gradient(#fff 0%, #fdfdfd 16%, #fbfbfb 33%, #f8f8f8 49%, #efefef 66%, #dfdfdf 82%, #bfbfbf 100%);
|
||||
opacity: 0.8;
|
||||
cursor: default;
|
||||
}
|
||||
.psv-overlay-image {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.psv-overlay-image svg {
|
||||
width: 50%;
|
||||
}
|
||||
@media (orientation: landscape) {
|
||||
.psv-overlay-image svg {
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
.psv-overlay-title {
|
||||
color: black;
|
||||
margin-top: 1em;
|
||||
font: 30px sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
.psv-overlay-text {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
font: 20px sans-serif;
|
||||
opacity: 0.8;
|
||||
text-align: center;
|
||||
}
|
||||
.psv-panel {
|
||||
position: absolute;
|
||||
z-index: 90;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
width: 400px;
|
||||
max-width: calc(100% - 9px);
|
||||
background: rgba(10, 10, 10, 0.7);
|
||||
transform: translate3d(100%, 0, 0);
|
||||
opacity: 0;
|
||||
transition-property: opacity, transform;
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: 100ms;
|
||||
cursor: default;
|
||||
margin-left: 9px;
|
||||
}
|
||||
.psv--has-navbar .psv-panel {
|
||||
height: calc(100% - 40px);
|
||||
}
|
||||
.psv-panel-close-button {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: 0;
|
||||
width: 19.2px;
|
||||
height: 19.2px;
|
||||
padding: 6.4px;
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
transition: background 300ms ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
.psv-panel-close-button svg {
|
||||
transition: transform 300ms ease-in-out;
|
||||
}
|
||||
.psv-panel-close-button:hover {
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
.psv-panel-close-button:hover svg {
|
||||
transform: scale(-1);
|
||||
}
|
||||
.psv-panel-resizer {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9px;
|
||||
width: 9px;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
cursor: col-resize;
|
||||
}
|
||||
.psv-panel-resizer::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 1px;
|
||||
margin-top: -14.5px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
box-shadow:
|
||||
1px 0 #fff,
|
||||
3px 0px #fff,
|
||||
5px 0px #fff,
|
||||
1px 2px #fff,
|
||||
3px 2px #fff,
|
||||
5px 2px #fff,
|
||||
1px 4px #fff,
|
||||
3px 4px #fff,
|
||||
5px 4px #fff,
|
||||
1px 6px #fff,
|
||||
3px 6px #fff,
|
||||
5px 6px #fff,
|
||||
1px 8px #fff,
|
||||
3px 8px #fff,
|
||||
5px 8px #fff,
|
||||
1px 10px #fff,
|
||||
3px 10px #fff,
|
||||
5px 10px #fff,
|
||||
1px 12px #fff,
|
||||
3px 12px #fff,
|
||||
5px 12px #fff,
|
||||
1px 14px #fff,
|
||||
3px 14px #fff,
|
||||
5px 14px #fff,
|
||||
1px 16px #fff,
|
||||
3px 16px #fff,
|
||||
5px 16px #fff,
|
||||
1px 18px #fff,
|
||||
3px 18px #fff,
|
||||
5px 18px #fff,
|
||||
1px 20px #fff,
|
||||
3px 20px #fff,
|
||||
5px 20px #fff,
|
||||
1px 22px #fff,
|
||||
3px 22px #fff,
|
||||
5px 22px #fff,
|
||||
1px 24px #fff,
|
||||
3px 24px #fff,
|
||||
5px 24px #fff,
|
||||
1px 26px #fff,
|
||||
3px 26px #fff,
|
||||
5px 26px #fff,
|
||||
1px 28px #fff,
|
||||
3px 28px #fff,
|
||||
5px 28px #fff;
|
||||
background: transparent;
|
||||
}
|
||||
.psv-panel-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
color: rgb(220, 220, 220);
|
||||
font: 16px sans-serif;
|
||||
overflow: auto;
|
||||
}
|
||||
.psv-panel-content:not(.psv-panel-content--no-margin) {
|
||||
padding: 1em;
|
||||
}
|
||||
.psv-panel-content--no-interaction {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.psv-panel--open {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
transition-duration: 0.2s;
|
||||
}
|
||||
.psv-panel--open .psv-panel-close-button,
|
||||
.psv-panel--open .psv-panel-resizer {
|
||||
display: block;
|
||||
}
|
||||
@media screen and (max-width: 400px) {
|
||||
.psv-panel {
|
||||
width: 100% !important;
|
||||
max-width: none;
|
||||
}
|
||||
.psv-panel-resizer {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
.psv-panel-menu {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.psv-panel-menu-title {
|
||||
flex: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font: 24px sans-serif;
|
||||
margin: 24px 12px;
|
||||
}
|
||||
.psv-panel-menu-title svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.psv-panel-menu-list {
|
||||
flex: 1;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.psv-panel-menu-item {
|
||||
min-height: 1.5em;
|
||||
padding: 0.5em 1em;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
transition: background 0.1s ease-in-out;
|
||||
}
|
||||
.psv-panel-menu-item--active {
|
||||
outline: 1px solid currentcolor;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
.psv-panel-menu-item-icon {
|
||||
flex: none;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.psv-panel-menu-item-icon img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
.psv-panel-menu-item-icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.psv-panel-menu-item:focus-visible {
|
||||
outline: 2px solid #007cff;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
.psv-panel-menu--stripped .psv-panel-menu-item:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(odd),
|
||||
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(odd)::before {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(even),
|
||||
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(even)::before {
|
||||
background: transparent;
|
||||
}
|
||||
.psv-container:not(.psv--is-touch) .psv-panel-menu-item:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
.psv-tooltip {
|
||||
position: absolute;
|
||||
z-index: 50;
|
||||
box-sizing: border-box;
|
||||
max-width: 200px;
|
||||
background: rgba(61, 61, 61, 0.8);
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
transition-property: opacity, transform;
|
||||
transition-timing-function: ease-in-out;
|
||||
transition-duration: 100ms;
|
||||
cursor: default;
|
||||
}
|
||||
.psv-tooltip-content {
|
||||
color: rgb(255, 255, 255);
|
||||
font: 14px sans-serif;
|
||||
text-shadow: 0 1px #000;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
.psv-tooltip-arrow {
|
||||
position: absolute;
|
||||
height: 0;
|
||||
width: 0;
|
||||
border: 7px solid transparent;
|
||||
}
|
||||
.psv-tooltip--top-left,
|
||||
.psv-tooltip--top-center,
|
||||
.psv-tooltip--top-right {
|
||||
transform: translate3d(0, 5px, 0);
|
||||
}
|
||||
.psv-tooltip--top-left .psv-tooltip-arrow,
|
||||
.psv-tooltip--top-center .psv-tooltip-arrow,
|
||||
.psv-tooltip--top-right .psv-tooltip-arrow {
|
||||
border-top-color: rgba(61, 61, 61, 0.8);
|
||||
}
|
||||
.psv-tooltip--bottom-left,
|
||||
.psv-tooltip--bottom-center,
|
||||
.psv-tooltip--bottom-right {
|
||||
transform: translate3d(0, -5px, 0);
|
||||
}
|
||||
.psv-tooltip--bottom-left .psv-tooltip-arrow,
|
||||
.psv-tooltip--bottom-center .psv-tooltip-arrow,
|
||||
.psv-tooltip--bottom-right .psv-tooltip-arrow {
|
||||
border-bottom-color: rgba(61, 61, 61, 0.8);
|
||||
}
|
||||
.psv-tooltip--left-top,
|
||||
.psv-tooltip--center-left,
|
||||
.psv-tooltip--left-bottom {
|
||||
transform: translate3d(5px, 0, 0);
|
||||
}
|
||||
.psv-tooltip--left-top .psv-tooltip-arrow,
|
||||
.psv-tooltip--center-left .psv-tooltip-arrow,
|
||||
.psv-tooltip--left-bottom .psv-tooltip-arrow {
|
||||
border-left-color: rgba(61, 61, 61, 0.8);
|
||||
}
|
||||
.psv-tooltip--right-top,
|
||||
.psv-tooltip--center-right,
|
||||
.psv-tooltip--right-bottom {
|
||||
transform: translate3d(-5px, 0, 0);
|
||||
}
|
||||
.psv-tooltip--right-top .psv-tooltip-arrow,
|
||||
.psv-tooltip--center-right .psv-tooltip-arrow,
|
||||
.psv-tooltip--right-bottom .psv-tooltip-arrow {
|
||||
border-right-color: rgba(61, 61, 61, 0.8);
|
||||
}
|
||||
.psv-tooltip--left-top,
|
||||
.psv-tooltip--top-left {
|
||||
box-shadow: -3px -3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--top-center {
|
||||
box-shadow: 0 -3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--right-top,
|
||||
.psv-tooltip--top-right {
|
||||
box-shadow: 3px -3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--left-bottom,
|
||||
.psv-tooltip--bottom-left {
|
||||
box-shadow: -3px 3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--bottom-center {
|
||||
box-shadow: 0 3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--right-bottom,
|
||||
.psv-tooltip--bottom-right {
|
||||
box-shadow: 3px 3px 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--center-left {
|
||||
box-shadow: -3px 0 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--center-right {
|
||||
box-shadow: 3px 0 0 rgba(90, 90, 90, 0.7);
|
||||
}
|
||||
.psv-tooltip--visible {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
/*# sourceMappingURL=index.css.map */
|
||||
6567
src/renderer/public/vrHtml/@photo-sphere-viewer/core/index.js
Normal file
@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* PhotoSphereViewer.MarkersPlugin 5.7.3
|
||||
* @copyright 2024 Damien "Mistic" Sorel
|
||||
* @licence MIT (https://opensource.org/licenses/MIT)
|
||||
*/
|
||||
/* src/style.scss */
|
||||
.psv-container {
|
||||
--psv-markers-plugin-loaded: true;
|
||||
}
|
||||
.psv-markers {
|
||||
user-select: none;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.psv-markers-svg-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 20;
|
||||
}
|
||||
.psv-marker {
|
||||
display: none;
|
||||
}
|
||||
.psv-marker--normal {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 30;
|
||||
overflow: visible;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.psv-marker--transparent {
|
||||
display: block;
|
||||
opacity: 0;
|
||||
}
|
||||
.psv-marker--visible {
|
||||
display: block;
|
||||
}
|
||||
.psv-marker--has-tooltip,
|
||||
.psv-marker--has-content {
|
||||
cursor: pointer;
|
||||
}
|
||||
/*# sourceMappingURL=index.css.map */
|
||||
115
src/renderer/public/vrHtml/index.html
Normal file
@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!-- 传整个数组节点 -->
|
||||
|
||||
<head>
|
||||
<!-- for optimal display on high DPI devices -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="stylesheet" href="@photo-sphere-viewer/core/index.css" />
|
||||
<link rel="stylesheet" href="@photo-sphere-viewer/markers-plugin/index.css" />
|
||||
<script src="./three.min.js"></script>
|
||||
<script type="module">
|
||||
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
function setIframe(data, str) {
|
||||
load(data, str)
|
||||
}
|
||||
</script>
|
||||
<!-- <script type="module">
|
||||
import * as THREE from './three.min.js';
|
||||
window.THREE = THREE;
|
||||
console.log(THREE)
|
||||
</script> -->
|
||||
<script src="@photo-sphere-viewer/core/index.js"></script>
|
||||
<script src="@photo-sphere-viewer/markers-plugin/index.js"></script>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<!-- the viewer container must have a defined size -->
|
||||
<div id="viewer" style="width: 100vw; height: 100vh;"></div>
|
||||
|
||||
<script>
|
||||
function load(path, str) {
|
||||
let url = new URL(path)
|
||||
let options = {}
|
||||
if (str.length) {
|
||||
let obj = JSON.parse(str)
|
||||
options.markers = initMarker(obj.neighbors)
|
||||
}
|
||||
|
||||
const viewer = new PhotoSphereViewer.Viewer({
|
||||
container: document.querySelector('#viewer'),
|
||||
// panorama: "http://localhost:8890/yjearth4.0/api/v1/vr/97ef82188bc7e2d074502c5730e2b3ec.jpg",
|
||||
panorama: path,
|
||||
plugins: [
|
||||
[PhotoSphereViewer.MarkersPlugin, options],
|
||||
],
|
||||
});
|
||||
const markersPlugin = viewer.getPlugin(PhotoSphereViewer.MarkersPlugin);
|
||||
markersPlugin.addEventListener('select-marker', ({ marker }) => {
|
||||
let str = marker.config.myPath
|
||||
window.marker = marker
|
||||
let imgUrl = `${url.origin}/yjearth4.0/api/v1/vr/${str}.jpg`
|
||||
let json = `${url.origin}/yjearth4.0/api/v1/vr/${str}.json`
|
||||
let markers = undefined
|
||||
fetch(json).then(res => {
|
||||
if (res.ok) {
|
||||
res.json().then(json => {
|
||||
markers = initMarker(json.neighbors)
|
||||
add(imgUrl, markers)
|
||||
})
|
||||
} else {
|
||||
add(imgUrl)
|
||||
}
|
||||
})
|
||||
});
|
||||
function add(imgUrl, markers) {
|
||||
viewer.setPanorama(imgUrl, {})
|
||||
viewer.animate({
|
||||
zoom: 100,
|
||||
speed: "-2rpm",
|
||||
}).then(() => {
|
||||
markersPlugin.clearMarkers()
|
||||
if (markers) {
|
||||
markersPlugin.setMarkers(markers)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function initMarker(arr) {
|
||||
let markers = []
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const element = arr[i];
|
||||
console.log(Math.atan2(Math.sin(element.position.lng), Math.cos(element.position.lat)))
|
||||
let obji = {
|
||||
id: 'image' + i,
|
||||
image: './定位.png',
|
||||
tooltip: element.name,
|
||||
position: { yaw: element.degree + 'deg', pitch: '1deg' },
|
||||
size: { width: 32, height: 32 },
|
||||
myPath: element.node_id,
|
||||
data: {
|
||||
generated: true,
|
||||
},
|
||||
}
|
||||
markers.push(obji)
|
||||
}
|
||||
return markers
|
||||
}
|
||||
</script>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
src/renderer/public/vrHtml/sun.jpg
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
7
src/renderer/public/vrHtml/three.min.js
vendored
Normal file
BIN
src/renderer/public/vrHtml/定位.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
@ -7,5 +7,12 @@ export const GisApi = {
|
||||
url: `/fileInfo/upload`,
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
uploadLocationImage: async (data: any) => {
|
||||
return await request.post({
|
||||
url: `/source/uploadLocationImage`,
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
1
src/renderer/src/auto-imports.d.ts
vendored
@ -8,6 +8,7 @@ export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
|
||||
@ -19,7 +19,7 @@ if (window && window.process && window.process.type === 'renderer') {
|
||||
// 创建自定义配置的axios实例
|
||||
const service: AxiosInstance = axios.create({
|
||||
baseURL: baseURL,
|
||||
timeout: 10000,
|
||||
timeout: 300000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Access-Control-Allow-Origin': '*'
|
||||
|
||||
@ -43,5 +43,6 @@ export const addMapSource = async ({ type, id, sourceName = '未命名对象', o
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import { leftClick, rightClick } from '../../src/views/components/tree/entityClick'
|
||||
export const initMapData = async (type, data) => {
|
||||
let entityObject
|
||||
let options
|
||||
@ -16,7 +17,10 @@ export const initMapData = async (type, data) => {
|
||||
entityObject = new YJ.Obj.StandText(window.earth, data)
|
||||
break
|
||||
case 'point':
|
||||
case 'linkImage':
|
||||
case 'vrImage':
|
||||
entityObject = new YJ.Obj.BillboardObject(window.earth, data)
|
||||
entityObject.options.billboard.defaultImage=''
|
||||
break
|
||||
case 'line':
|
||||
entityObject = await new YJ.Obj.PolylineObject(window.earth, data)
|
||||
@ -99,6 +103,14 @@ export const initMapData = async (type, data) => {
|
||||
}
|
||||
options = structuredClone(entityObject.options)
|
||||
delete options.host
|
||||
//鼠标左键点击事件
|
||||
entityObject.onClick = () => {
|
||||
leftClick(options);
|
||||
};
|
||||
//鼠标右键点击事件
|
||||
entityObject.onRightClick = () => {
|
||||
rightClick(options);
|
||||
};
|
||||
// options = entityObject
|
||||
return options
|
||||
}
|
||||
|
||||
@ -34,9 +34,9 @@ const i18n = createI18n({
|
||||
'zh-TW': zhTW,
|
||||
'zh-EN': zhEN
|
||||
}
|
||||
})
|
||||
});
|
||||
// 注册全局指令
|
||||
|
||||
(window as any)._winMap = new Map();
|
||||
const setApp = createApp(App)
|
||||
// 定义全局方法
|
||||
|
||||
|
||||
@ -133,12 +133,13 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const title = ref('圆')
|
||||
const baseDialog: any = ref(null);
|
||||
@ -320,8 +321,31 @@ const close = () => {
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@ -362,7 +362,10 @@ const linkDelete = (index: any) => {
|
||||
attribute.value.link.content.splice(index, 1)
|
||||
}
|
||||
const linkConfirmEdit = (index: string | number) => {
|
||||
attribute.value.link.content[index] = linkEditActive.value
|
||||
attribute.value.link.content[index] = {
|
||||
name: linkEditActive.value.name,
|
||||
url: linkEditActive.value.url
|
||||
}
|
||||
linkEditActive.value = {}
|
||||
}
|
||||
const linkCancelEdit = () => {
|
||||
|
||||
@ -460,12 +460,13 @@
|
||||
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 { getFontList } from './fontSelect'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -771,8 +772,32 @@ const fontChange = (val) => {
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
// 用户点击取消,不执行任何操作
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
|
||||
@ -112,11 +112,12 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
@ -129,7 +130,7 @@ const activeName = ref('1')
|
||||
const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const circle:any = ref([])
|
||||
const circle: any = ref([])
|
||||
const colorRefs = ref<(Element | ComponentPublicInstance | null)[]>([])
|
||||
const open = async (id: any) => {
|
||||
that = window.earth.entityMap.get(id)
|
||||
@ -272,8 +273,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.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 translate = () => {
|
||||
that.openPositionEditing(() => {
|
||||
|
||||
@ -287,13 +287,14 @@
|
||||
import { ref, getCurrentInstance } 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 { getFontList } from './fontSelect'
|
||||
import attribute from './attribute.vue'
|
||||
import labelStyle from './labelStyle.vue'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -546,8 +547,31 @@ const close = () => {
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@ -86,9 +86,10 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
@ -142,8 +143,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.remove()
|
||||
close()
|
||||
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 translate = () => {
|
||||
entityOptions.value.positionEditing = true
|
||||
|
||||
@ -67,7 +67,7 @@ const confirm = () => {
|
||||
brightness: entityOptions.value.brightness,
|
||||
name: entityOptions.value.name,
|
||||
show: entityOptions.value.show,
|
||||
id: entityOptions.value.id,
|
||||
id: entityOptions.value.options.id,
|
||||
}
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
|
||||
@ -133,12 +133,13 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const title = ref('面')
|
||||
const baseDialog: any = ref(null);
|
||||
@ -327,8 +328,32 @@ const close = () => {
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
// 用户点击取消,不执行任何操作
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@ -295,12 +295,13 @@
|
||||
import { ref, getCurrentInstance } 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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -553,8 +554,32 @@ const close = () => {
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
// 用户点击取消,不执行任何操作
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@ -75,11 +75,12 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
@ -137,8 +138,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.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 changeRadius = (val)=>{
|
||||
if (radiusUnit.value == 'km') {
|
||||
|
||||
@ -47,9 +47,10 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
@ -101,8 +102,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
that.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 nodeEdit = () => {
|
||||
that.nodeEdit()
|
||||
|
||||
108
src/renderer/src/views/components/propertyBox/terrain.vue
Normal file
@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<Dialog ref="baseDialog" title="底图属性" left="calc(50% - 160px)" top="calc(50% - 120px)" :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>
|
||||
</div>
|
||||
</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 { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
import { useTreeNode } from '../tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
const text = ref('')
|
||||
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()
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
baseDialog.value?.close()
|
||||
let params = {
|
||||
name: entityOptions.value.name,
|
||||
show: entityOptions.value.show,
|
||||
id: entityOptions.value.options.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) })
|
||||
}
|
||||
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(() => {
|
||||
// 用户点击取消,不执行任何操作
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
@ -39,6 +39,14 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div style="position: absolute; left: 24px; display: flex;">
|
||||
<button @click="rotate"><svg class="icon-edit">
|
||||
<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>平移</button>
|
||||
</div>
|
||||
<button @click="remove">删除</button>
|
||||
<button @click="confirm">确定</button>
|
||||
<button @click="close">关闭</button>
|
||||
@ -50,10 +58,11 @@
|
||||
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 '../tree/hooks/treeNode'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -65,27 +74,43 @@ const entityOptions: any = ref({});
|
||||
let originalOptions: any
|
||||
let that: any
|
||||
const closeCallback = () => {
|
||||
entityOptions.value.originalOptions = structuredClone(originalOptions)
|
||||
entityOptions.value.oldData = 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)
|
||||
originalOptions = structuredClone(that.newData)
|
||||
entityOptions.value = that
|
||||
baseDialog.value?.open()
|
||||
await nextTick()
|
||||
}
|
||||
const confirm = () => {
|
||||
originalOptions = structuredClone(that.options)
|
||||
originalOptions = structuredClone(that.newData)
|
||||
baseDialog.value?.close()
|
||||
let params = structuredClone(that.options)
|
||||
let params = {
|
||||
id: that.options.id,
|
||||
orientation: {
|
||||
roll: that.roll,
|
||||
pitch: that.pitch,
|
||||
heading: that.heading,
|
||||
},
|
||||
position: {
|
||||
lng: that.lng,
|
||||
lat: that.lat,
|
||||
alt: that.height,
|
||||
},
|
||||
customView: that.customView ? structuredClone(that.customView):undefined,
|
||||
show: that.show,
|
||||
name: that.name,
|
||||
accuracy: that.accuracy,
|
||||
transparency: that.transparency,
|
||||
}
|
||||
// 删除不必要的属性
|
||||
delete params.host
|
||||
let params2 = {
|
||||
"id": params.id,
|
||||
"sourceName": params.text,
|
||||
"sourceName": params.name,
|
||||
"params": params,
|
||||
"isShow": params.show ? 1 : 0,
|
||||
}
|
||||
@ -95,9 +120,41 @@ const confirm = () => {
|
||||
const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const rotate = () => {
|
||||
that.rotationEditing = true
|
||||
}
|
||||
const translate = () => {
|
||||
that.openPositionEditing(()=>{
|
||||
entityOptions.value.height = entityOptions.value.height
|
||||
})
|
||||
}
|
||||
const remove = () => {
|
||||
that.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(() => {
|
||||
// 用户点击取消,不执行任何操作
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
open,
|
||||
|
||||
@ -216,11 +216,12 @@
|
||||
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 '../tree/hooks/treeNode'
|
||||
import { getFontList } from './fontSelect'
|
||||
|
||||
const { cusUpdateNode } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -282,8 +283,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
that.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 clickChangeModel = () => { }
|
||||
const modelRotate = () => {
|
||||
|
||||
@ -80,11 +80,12 @@
|
||||
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 } = useTreeNode()
|
||||
const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
|
||||
|
||||
const baseDialog: any = ref(null);
|
||||
const eventBus: any = inject("bus");
|
||||
@ -163,8 +164,32 @@ const close = () => {
|
||||
baseDialog.value?.close()
|
||||
}
|
||||
const remove = () => {
|
||||
entityOptions.value.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()
|
||||
|
||||
368
src/renderer/src/views/components/selectImg/index.vue
Normal file
@ -0,0 +1,368 @@
|
||||
<template>
|
||||
<!-- <div class="selectImg" > -->
|
||||
<Dialog class="selectImg" id="imgBox" ref="baseDialog" title="图标选择">
|
||||
<template #content>
|
||||
<div class="boxBody">
|
||||
<el-tabs v-model="activeName" type="card">
|
||||
<template v-if="hasGEMarker1">
|
||||
<el-tab-pane label="立体图标" name="GEMarker1">
|
||||
<div class="imgItem" :style="item.selected ? 'border-color:red' : ''" v-for="item in imgList_GEMarker1s"
|
||||
:key="item.key + 'GEMarker1s'" @click="selectImg(item)">
|
||||
<img :src="item.url" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
<el-tab-pane label="普通图标" name="GEMarker">
|
||||
<div class="imgItem" :style="item.selected ? 'border-color:red' : ''" v-for="item in imgList_GEMarker"
|
||||
:key="item.key + 'GEMarker'" @click="selectImg(item)">
|
||||
<img :src="item.url" />
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane class="zidingyi" label="自定义图标" name="GEMarkerz">
|
||||
<!-- http://192.168.110.19:8891/yjearth4.0/api/v1/user/addRole -->
|
||||
<div style="display: flex;">
|
||||
<el-upload class="upload-demo" :action="url + '/yjearth4.0/api/v1' + '/icon/upload'" multiple
|
||||
:file-list="fileList" :show-file-list="false" accept=".png,.jpg,.jpge" :on-success="onSuccess">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
</el-upload>
|
||||
<el-button style="margin-left: 10px;" type="primary" :disabled="imgList_zidingyi.length == 0"
|
||||
@click="handleCheckAllChange" size="small">全选</el-button>
|
||||
<!-- <el-checkbox-group style="margin-left: 10px;" v-model="isIndeterminate" size="small"
|
||||
@change="handleCheckAllChange">
|
||||
<el-checkbox-button>全选</el-checkbox-button>
|
||||
</el-checkbox-group> -->
|
||||
<!-- 这里全选和取消全选 -->
|
||||
<el-button style="margin-left: 10px;" size="small" type="primary" @click="delImg">删除</el-button>
|
||||
</div>
|
||||
<div style="display: flex;" class="sssssssssss">
|
||||
<el-checkbox-group v-model="checkList">
|
||||
<el-checkbox :label="item.id" v-for="item in imgList_zidingyi" :key="item.id" style="padding-left: 0;">
|
||||
<div class="imgItem" :class="{ selectImg1: selectedId == item.id }"
|
||||
:style="item.selected ? 'border-color:red' : ''" @click="selectImg(item)">
|
||||
<img :src="url + '/yjearth4.0/api/v1/icon/' + item.id + '/' + item.suffix" />
|
||||
</div>
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</Dialog>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { zidinyi, deleteIcon } from "../api/gisAPI"
|
||||
import Dialog from '@/components/dialog/baseDialog.vue'
|
||||
export default {
|
||||
name: "selectImg",
|
||||
data() {
|
||||
return {
|
||||
activeName: "GEMarker",
|
||||
imgList_GEMarker: [],
|
||||
imgList_GEMarker1: [],
|
||||
imgList_GEMarker1s: [],
|
||||
imgList_zidingyi: [],
|
||||
fileList: [],
|
||||
checkList: [],
|
||||
hasGEMarker1: true,
|
||||
flag: null,
|
||||
url: '',
|
||||
isIndeterminate: false,
|
||||
checkAll: true,
|
||||
isAll: false,
|
||||
selectedId: '',
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// $(".selectImg .el-tab-pane").addClass("custom_scroll_bar")
|
||||
// this.getList();
|
||||
},
|
||||
methods: {
|
||||
// 这里全选和取消全选
|
||||
handleCheckAllChange() {
|
||||
let arr = this.imgList_zidingyi.map(item => {
|
||||
return item.id
|
||||
})
|
||||
this.isAll = !this.isAll
|
||||
this.checkList = this.isAll ? arr : [];
|
||||
},
|
||||
// 删除
|
||||
delImg() {
|
||||
let arr = []
|
||||
this.imgList_zidingyi.filter(item => {
|
||||
if (this.checkList.includes(item.id)) {
|
||||
arr.push({
|
||||
id: item.id,
|
||||
suffix: item.suffix
|
||||
})
|
||||
}
|
||||
})
|
||||
if (arr.length == 0) {
|
||||
this.$message.warning("请选择要删除的图标");
|
||||
return
|
||||
}
|
||||
// deleteIcon({ icons: arr }).then(res => {
|
||||
// if (res.code == 0) {
|
||||
// this.$message.success("删除成功");
|
||||
// this.getList()
|
||||
// }
|
||||
// })
|
||||
},
|
||||
//获取列表
|
||||
getList(url) {
|
||||
// zidinyi({}, data => {
|
||||
// this.imgList_zidingyi = data.list || []
|
||||
// if (url) {
|
||||
// this.selectedId = this.getIdFromUrl(url.pathname)
|
||||
// }
|
||||
// })
|
||||
},
|
||||
getIdFromUrl(url) {
|
||||
const regex = /\/icon\/([^\/]+)\//;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null;
|
||||
},
|
||||
onSuccess(file) {
|
||||
this.getList()
|
||||
},
|
||||
selectImg(item) {
|
||||
let selectedImg
|
||||
let onLine = false
|
||||
if (!item.key) {
|
||||
onLine = true
|
||||
selectedImg = '/yjearth4.0/api/v1/icon/' + item.id + '/' + item.suffix
|
||||
} else {
|
||||
selectedImg = item.key.indexOf("1s/") > -1 ? item.key.replace(/1s/g, "1") : item.key;
|
||||
}
|
||||
this.$sendChanel("selectedImg", { img: selectedImg, flag: this.flag, onLine });
|
||||
this.close();
|
||||
},
|
||||
close() {
|
||||
this.$changeComponentShow(".selectImgBox", false);
|
||||
this.checkList = []
|
||||
},
|
||||
set(key) {
|
||||
this.flag = key
|
||||
},
|
||||
init(obj, selected, hasGEMarker1 = true, isUrl) {
|
||||
let selectedd
|
||||
if (isUrl) {
|
||||
this.getList(new URL(selected))
|
||||
} else {
|
||||
this.getList()
|
||||
}
|
||||
console.log('obj, selectedobj, selectedobj, selectedobj, selected', obj, selected, this.imgList_zidingyi);
|
||||
let arr = selected.split("/");
|
||||
if (selected.includes('/yjearth4.0/api/v1/icon/')) {
|
||||
const parts = selected.split("/");
|
||||
selectedd = parts[parts.indexOf("icon") + 1];
|
||||
this.activeName = 'GEMarkerz';
|
||||
} else {
|
||||
console.log('selected1111', selected, arr);
|
||||
this.activeName = arr[0];
|
||||
}
|
||||
this.hasGEMarker1 = hasGEMarker1;
|
||||
this.url = localStorage.getItem('service')
|
||||
|
||||
for (const objKey in obj) {
|
||||
let imgList = [];
|
||||
obj[objKey].forEach((item) => {
|
||||
// console.log(
|
||||
// arr[0].indexOf("GEMarker1") > -1
|
||||
// ? `${arr[0]}s`
|
||||
// : arr[0] + "/" + arr[1]
|
||||
// );
|
||||
// 特定一个数据排到第一个
|
||||
if (item == "GEMarker1s/A-ablu-blank.png") {
|
||||
imgList.unshift({
|
||||
key: item,
|
||||
selected:
|
||||
item ==
|
||||
(arr[0].indexOf("GEMarker1") > -1 ? `${arr[0]}s` : arr[0]) +
|
||||
"/" +
|
||||
arr[1],
|
||||
url: "http://localhost:" + window.staticPort + "/" + item,
|
||||
});
|
||||
} else {
|
||||
imgList.push({
|
||||
key: item,
|
||||
selected:
|
||||
item ==
|
||||
(arr[0].indexOf("GEMarker1") > -1 ? `${arr[0]}s` : arr[0]) +
|
||||
"/" +
|
||||
arr[1],
|
||||
url: "http://localhost:" + window.staticPort + "/" + item,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this["imgList_" + objKey] = imgList;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.sssssssssss {
|
||||
.el-checkbox__label {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.selectImg {
|
||||
// border: 1px solid red;
|
||||
width: 30vw;
|
||||
min-height: 21vw;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #b2e3eff0;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 45%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: linear-gradient(0deg, rgba(0, 255, 255, 0.2) 0%, rgba(0, 255, 255, 0) 100%), rgba(0, 0, 0, 0.6);
|
||||
border: 1.5px solid rgba(0, 255, 255, 1);
|
||||
padding: 10px;
|
||||
backdrop-filter: blur(2px);
|
||||
|
||||
.el-tabs__item {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.el-tabs__item.is-active,
|
||||
.el-tabs__item:hover {
|
||||
color: rgba(0, 255, 255, 1);
|
||||
}
|
||||
|
||||
.el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
|
||||
border-bottom-color: rgba(0, 255, 255, 1)
|
||||
}
|
||||
|
||||
.el-tabs--card>.el-tabs__header {
|
||||
border-color: rgba(204, 204, 204, 0.2);
|
||||
}
|
||||
|
||||
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
|
||||
.el-tab-pane::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #f5f5f5;
|
||||
margin-left: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/*定义滚动条轨道 内阴影+圆角*/
|
||||
.el-tab-pane::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/*定义滑块 内阴影+圆角*/
|
||||
.el-tab-pane::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
-webkit-box-shadow: inset 0 0 6px rgb(0, 217, 255);
|
||||
background-color: #0bf7f7;
|
||||
}
|
||||
|
||||
.el-tabs--card>.el-tabs__header .el-tabs__nav {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-tabs--card>.el-tabs__header .el-tabs__item {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.boxHeader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
padding-bottom: 15px;
|
||||
|
||||
.title_img {
|
||||
width: 229px;
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
background: url('../assets/images/titlebg.png') no-repeat;
|
||||
}
|
||||
|
||||
.header_close {
|
||||
position: absolute;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
width: 30px;
|
||||
top: -1px;
|
||||
background: rgb(0 255 255 / 50%);
|
||||
right: 0;
|
||||
border-radius: 0 0 0 90%;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
font-size: 18px;
|
||||
// font-weight: 900;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.boxBody {
|
||||
display: flex;
|
||||
|
||||
.el-checkbox-button__inner {
|
||||
padding: 8px 15px;
|
||||
border-radius: 3px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.zidingyi {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-checkbox {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.imgItem {
|
||||
padding: 5px;
|
||||
border: 1px solid transparent;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
& {
|
||||
border-color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.selectImg1 {
|
||||
cursor: pointer;
|
||||
border-color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -2,8 +2,9 @@ import { TreeApi } from '@/api/tree'
|
||||
import { $changeComponentPop } from '@/utils/communication'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
|
||||
import { initMapData } from '../../../../../common/initMapData'
|
||||
import { initMapData } from '@/common/initMapData'
|
||||
import { GisApi } from '@/api/gisApi'
|
||||
import { addMapSource } from '@/common/addMapSource'
|
||||
const { cusAddNodes } = useTreeNode()
|
||||
|
||||
export const useRightOperate = () => {
|
||||
@ -58,11 +59,17 @@ export const useRightOperate = () => {
|
||||
// 提取后缀并转换为小写进行比较
|
||||
const extension = filePaths[0].slice(lastDotIndex + 1).toLowerCase();
|
||||
|
||||
let params2:any = {}
|
||||
if(extension === 'mbtiles') {
|
||||
let params2: any = {
|
||||
id: id,
|
||||
show: true,
|
||||
}
|
||||
if (extension === 'mbtiles') {
|
||||
params2.alpha = 1
|
||||
params2.brightness = 1
|
||||
}
|
||||
if (extension === 'apk') {
|
||||
// params2.exaggeration = 1
|
||||
}
|
||||
|
||||
|
||||
let params: any = {
|
||||
@ -79,17 +86,20 @@ export const useRightOperate = () => {
|
||||
message: '添加成功',
|
||||
type: 'success'
|
||||
})
|
||||
res.data.id = id
|
||||
let params = JSON.parse(res.data.params)
|
||||
res.data.params = JSON.parse(res.data.params)
|
||||
if (!res.data.params.name) {
|
||||
res.data.params.name = res.data.sourceName
|
||||
}
|
||||
if (!res.data.params.id) {
|
||||
res.data.params.id = res.data.id
|
||||
}
|
||||
let detail = JSON.parse(res.data.detail)
|
||||
if (!params.id) {
|
||||
params.id = res.data.id
|
||||
}
|
||||
if (!params.name) {
|
||||
params.name = res.data.sourceName
|
||||
}
|
||||
initMapData(res.data.sourceType, {...detail, ...params})
|
||||
cusAddNodes(window.treeObj, params.parentId, [{...detail, ...params}])
|
||||
let mapParams = { ...detail, ...res.data.params }
|
||||
|
||||
initMapData(res.data.sourceType, mapParams)
|
||||
res.data.params = JSON.stringify(res.data.params)
|
||||
res.data.detail = JSON.stringify(res.data.detail)
|
||||
cusAddNodes(window.treeObj, params.parentId, [res.data])
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -124,7 +134,7 @@ export const useRightOperate = () => {
|
||||
const fileHandles = await (window as any).showOpenFilePicker(pickerOpts);
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'vr')
|
||||
handleFileImgInput(files, parentId, 'vrImage')
|
||||
}
|
||||
else {
|
||||
let input = document.createElement('input')
|
||||
@ -134,7 +144,7 @@ export const useRightOperate = () => {
|
||||
input.click()
|
||||
input.addEventListener('input', async (e: any) => {
|
||||
let files = e.target.files
|
||||
handleFileImgInput(files, parentId, 'vr')
|
||||
handleFileImgInput(files, parentId, 'vrImage')
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -168,7 +178,7 @@ export const useRightOperate = () => {
|
||||
const fileHandles = await (window as any).showOpenFilePicker(pickerOpts);
|
||||
const files = await Promise.all(fileHandles.map(fileHandle => fileHandle.getFile()));
|
||||
const dataTransfer = new DataTransfer();
|
||||
handleFileImgInput(files, parentId, 'link')
|
||||
handleFileImgInput(files, parentId, 'linkImage')
|
||||
}
|
||||
else {
|
||||
let input = document.createElement('input')
|
||||
@ -178,7 +188,7 @@ export const useRightOperate = () => {
|
||||
input.click()
|
||||
input.addEventListener('input', async (e: any) => {
|
||||
let files = e.target.files
|
||||
handleFileImgInput(files, parentId, 'link')
|
||||
handleFileImgInput(files, parentId, 'linkImage')
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -191,10 +201,14 @@ export const useRightOperate = () => {
|
||||
//导入模型
|
||||
const addTrajectory = () => { }
|
||||
//编辑
|
||||
const editNode = (eventBus) => {
|
||||
let selectNodes = getSelectedNodes(window.treeObj);
|
||||
if (selectNodes && selectNodes[selectNodes.length - 1]) {
|
||||
let node = selectNodes[selectNodes.length - 1]
|
||||
const editNode = (eventBus, node) => {
|
||||
if (!node) {
|
||||
let selectNodes = getSelectedNodes(window.treeObj);
|
||||
if (selectNodes && selectNodes[selectNodes.length - 1]) {
|
||||
node = selectNodes[selectNodes.length - 1]
|
||||
}
|
||||
}
|
||||
if (node) {
|
||||
eventBus.emit("openDialog", node.sourceType, node.id);
|
||||
if (node.sourceType == 'pressModel') {
|
||||
eventBus.emit("openDialog", node.sourceType, node);
|
||||
@ -395,69 +409,62 @@ export const useRightOperate = () => {
|
||||
// 图片文件上传后续
|
||||
async function handleFileImgInput(files: any, parentId: string, type: string) {
|
||||
const formData = new FormData();
|
||||
let ids: any = []
|
||||
let filesList: any = []
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const element = files[i]
|
||||
ids.push(new YJ.Tools().randomString())
|
||||
filesList.push(element)
|
||||
formData.append('files', element)
|
||||
}
|
||||
let res = await GisApi.linkFile(formData)
|
||||
if (res.code == 0 || res.code == 200) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i]
|
||||
// 检查文件类型
|
||||
if (!file.type.match('image*')) {
|
||||
continue;
|
||||
let params: any = {
|
||||
"id": ids[0],
|
||||
"show": true,
|
||||
"near": 2000,
|
||||
"far": 100000,
|
||||
"scaleByDistance": true,
|
||||
"heightMode": 3,
|
||||
"billboard": {
|
||||
"show": true,
|
||||
"image": "http://localhost:5173/sdk/img/A-ablu-blank.png",
|
||||
"scale": 3
|
||||
},
|
||||
"label": {
|
||||
"show": true,
|
||||
"fontFamily": 0,
|
||||
"fontSize": 39,
|
||||
"color": "#00ffff"
|
||||
},
|
||||
"attribute": {
|
||||
"link": {
|
||||
"content": []
|
||||
},
|
||||
"vr": {
|
||||
"content": []
|
||||
},
|
||||
"camera": {
|
||||
"content": []
|
||||
},
|
||||
"isc": {
|
||||
"content": []
|
||||
},
|
||||
"goods": {
|
||||
"content": []
|
||||
}
|
||||
(window as any).EXIF.getData(file, async function (e) {
|
||||
let id = new YJ.Tools().randomString()
|
||||
let name = file.name.split('.')[0]
|
||||
// 获取所有EXIF数据
|
||||
// @ts-ignore
|
||||
const allMetaData = (window as any).getAllTags(this);
|
||||
let lngDMS = allMetaData.GPSLongitude[0] + '°' + allMetaData.GPSLongitude[1] + "'" + allMetaData.GPSLongitude[2] + '"'
|
||||
let latDMS = allMetaData.GPSLatitude[0] + '°' + allMetaData.GPSLatitude[1] + "'" + allMetaData.GPSLatitude[2] + '"'
|
||||
let lngDecimal = window.earth.proj.dmsToDecimal(lngDMS)
|
||||
let latDecimal = window.earth.proj.dmsToDecimal(latDMS)
|
||||
if (allMetaData.GPSLongitudeRef === 'W') {
|
||||
lngDecimal = -(Math.abs(lngDecimal))
|
||||
}
|
||||
if (allMetaData.GPSLatitudeRef === 'S') {
|
||||
latDecimal = -(Math.abs(latDecimal))
|
||||
}
|
||||
let options: any = await initMapData('point', {
|
||||
id: id,
|
||||
name: name,
|
||||
position: {
|
||||
lng: lngDecimal,
|
||||
lat: latDecimal,
|
||||
alt: allMetaData.GPSAltitude.valueOf()
|
||||
},
|
||||
attribute: {
|
||||
[type]: {
|
||||
content: [
|
||||
{
|
||||
"name": "带定位照片",
|
||||
"url": res.data[i].previewUrl
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
delete options.host
|
||||
let params: any = {
|
||||
id: id,
|
||||
sourceName: name,
|
||||
sourceType: 'point',
|
||||
// isShow: 1,
|
||||
parentId: parentId,
|
||||
// "treeIndex": 0,
|
||||
params: options
|
||||
}
|
||||
TreeApi.addOtherSource(params)
|
||||
params.params = JSON.stringify(params.params)
|
||||
params.isShow = true
|
||||
cusAddNodes(window.treeObj, params.parentId, [params])
|
||||
});
|
||||
},
|
||||
"richTextContent": ""
|
||||
}
|
||||
formData.append('ids', ids)
|
||||
formData.append('parentId', parentId)
|
||||
formData.append('sourceType', type)
|
||||
formData.append('params', JSON.stringify(params))
|
||||
let res = await GisApi.uploadLocationImage(formData)
|
||||
if (res.code == 0 || res.code == 200) {
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
let item = res.data[i]
|
||||
initMapData(type, JSON.parse(item.params))
|
||||
}
|
||||
cusAddNodes(window.treeObj, parentId, res.data)
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
||||
225
src/renderer/src/views/components/tree/entityClick.ts
Normal file
@ -0,0 +1,225 @@
|
||||
|
||||
let index = 0;
|
||||
let option = {
|
||||
width: 1300,
|
||||
height: 700,
|
||||
minWidth: 600,
|
||||
minHeight: 400,
|
||||
frame: true, //是否显示边缘框
|
||||
// simpleFullscreen: true,
|
||||
resizable: true,
|
||||
useContentSize: true,
|
||||
// icon: icon,
|
||||
// transparent: true,
|
||||
// fullScreen: true,
|
||||
// backgroundColor: '#00000000',
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
// devTools: true,
|
||||
// fullScreen: true,
|
||||
devTools: true,
|
||||
},
|
||||
}
|
||||
function leftClick(options) {
|
||||
console.log('leftClick', options)
|
||||
let id = options.id;
|
||||
let node = window.treeObj.getNodeByParam("id", id, null);
|
||||
console.log("node111111", node);
|
||||
const info = {
|
||||
text: options.richTextContent,
|
||||
// todo
|
||||
hrefs: options.attribute
|
||||
? options.attribute.link
|
||||
? options.attribute.link.content
|
||||
: []
|
||||
: [],
|
||||
camera: options.attribute
|
||||
? options.attribute.camera
|
||||
? options.attribute.camera.content
|
||||
: []
|
||||
: [],
|
||||
// 0827
|
||||
ISC: options.attribute
|
||||
? options.attribute.ISC
|
||||
? options.attribute.ISC.content
|
||||
: []
|
||||
: [],
|
||||
vr: options.attribute
|
||||
? options.attribute.vr
|
||||
? options.attribute.vr.content
|
||||
: []
|
||||
: [],
|
||||
goods: options.attribute
|
||||
? options.attribute.goods
|
||||
? options.attribute.goods.content
|
||||
: []
|
||||
: [],
|
||||
// camera: options.attribute? options.attribute.camera.content: {},
|
||||
// options.attributeType === "panorama" options.attribute.panorama.content[0]
|
||||
// : options.attributeType === "panorama" ? options.attribute.panorama.content[0].url
|
||||
// vrPath: node.source_type === "vr" ? options.url : "",
|
||||
source_path: node.sourcePath,
|
||||
env: localStorage.getItem("service"),
|
||||
};
|
||||
// // 0828
|
||||
// info.ISC &&
|
||||
// info.ISC.forEach((item) => {
|
||||
// item.previewUrl = "";
|
||||
// getIscPreviewURL({ cameraIndexCode: item.cameraIndexCode }, (res) => {
|
||||
// item.previewUrl = res.url;
|
||||
// });
|
||||
// });
|
||||
if (node) {
|
||||
if (
|
||||
!options.richTextContent &&
|
||||
!info.hrefs.length &&
|
||||
!info.vr.length &&
|
||||
!info.goods.length &&
|
||||
!info.camera.length
|
||||
) {
|
||||
// $root_home.$message.info("该标注标绘无属性信息");
|
||||
ElMessage({
|
||||
message: "该标注标绘无属性信息",
|
||||
type: "info",
|
||||
});
|
||||
} else {
|
||||
if (
|
||||
options.richTextContent ||
|
||||
info.hrefs.length ||
|
||||
info.vr.length ||
|
||||
info.goods.length
|
||||
) {
|
||||
tankuang(id, node, info);
|
||||
}
|
||||
// if (info.camera && info.camera.length) {
|
||||
// if (index == 0) {
|
||||
// ElMessage.success("摄像头打开中请稍后");
|
||||
// //测试
|
||||
// /* {
|
||||
// $root_home.$sendElectronChanel("openFFPlay", {
|
||||
// url: "WeChat_20230316160037.mp4" //res.data.flvUrl
|
||||
// });
|
||||
// }*/
|
||||
// cameraDataList(
|
||||
// {
|
||||
// page: 1,
|
||||
// pageSize: 9999,
|
||||
// },
|
||||
// (res) => {
|
||||
// let areaLists = res.list;
|
||||
// areaLists.forEach((element) => {
|
||||
// info.camera.forEach((item) => {
|
||||
// if (element.ID == item.ID) {
|
||||
// item.deviceId = element.deviceId;
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// info.camera.forEach((element) => {
|
||||
// index++;
|
||||
// getById({ deviceId: element.deviceId }, (res) => {
|
||||
// console.log(res);
|
||||
// if (res) {
|
||||
// $root_home.$sendElectronChanel("openFFPlay", {
|
||||
// url: res.rtspUrl, //
|
||||
// cameraName: res.cameraName, //
|
||||
// ip: res.ip, //
|
||||
// name: node.source_name,
|
||||
// deviceId: res.deviceId, //
|
||||
// });
|
||||
// $root_home.$recvElectronChanel(
|
||||
// "openFFPlayOut",
|
||||
// (e, err) => {
|
||||
// index--;
|
||||
// if (err) {
|
||||
// $root_home.$message.error("设备错误,打开失败!");
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// } else {
|
||||
// index--;
|
||||
// $root_home.$message.error("视频流错误,请检查设备用户名和密码");
|
||||
// }
|
||||
|
||||
// // start({
|
||||
// // streamName: arr[0],
|
||||
// // url: res.data.rtspUrl
|
||||
// // }).then(() => {
|
||||
// // $root_home.$sendElectronChanel("openFFPlay", {
|
||||
// // url: res.data.flvUrl //
|
||||
// // });
|
||||
// // });
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
// } else {
|
||||
// ElMessage.info("该摄像头已打开或未绑定");
|
||||
// }
|
||||
// //if (info.type == "vr")
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
function rightClick(options) {
|
||||
console.log("rightClick", options);
|
||||
let id = options.id;
|
||||
let node = window.treeObj.getNodeByParam("id", id, null);
|
||||
if (node) window.treeObj.selectNode(node);
|
||||
YJ.Global.splitScreen.setActiveId([id]);
|
||||
}
|
||||
|
||||
async function tankuang(id, node, info) {
|
||||
const { ipcRenderer, BrowserWindow } = require('electron')
|
||||
window.treeObj.selectNode(node);
|
||||
let baseURL = ''
|
||||
if (window && window.process && window.process.type === 'renderer') {
|
||||
// baseURL = localStorage.getItem('ip') ||'http://192.168.110.25:8848'|| 'http://127.0.0.1:8808'
|
||||
baseURL = 'http://127.0.0.1:8848'
|
||||
} else {
|
||||
baseURL = 'http://192.168.110.25:8848'
|
||||
}
|
||||
// console.log("node.detail.namenode.detail.namenode.detail.name", node.detail);
|
||||
if (!(window as any)._winMap.has(id)) {
|
||||
try {
|
||||
const windowId = await ipcRenderer.invoke('create-new-window', {
|
||||
...option,
|
||||
title: node.sourceName
|
||||
}, `${new URL(window.location.href).origin}/infoShow.html`, {
|
||||
info: info,
|
||||
host: baseURL,
|
||||
source_name: node.sourceName,
|
||||
source_type: node.sourceType,
|
||||
});
|
||||
(window as any)._winMap.set(id, windowId);
|
||||
} catch (error) {
|
||||
console.error('创建窗口失败:', error)
|
||||
}
|
||||
return
|
||||
let newDataWin = new win({
|
||||
...option,
|
||||
title: node.detail.name,
|
||||
});
|
||||
newDataWin.openDevTools(true);
|
||||
newDataWin.loadURL(`http://localhost:${staticPort}/infoShow.html`);
|
||||
|
||||
newDataWin.on("ready-to-show", () => {
|
||||
newDataWin.webContents.send("data", {
|
||||
info: info,
|
||||
source_name: node.source_name,
|
||||
source_type: node.source_type,
|
||||
});
|
||||
});
|
||||
|
||||
window._winMap.set(id, newDataWin.id);
|
||||
|
||||
newDataWin.on("close", function (event) {
|
||||
window._winMap.delete(id);
|
||||
});
|
||||
} else {
|
||||
BrowserWindow.fromId((window as any)._winMap.get(id)).show();
|
||||
}
|
||||
}
|
||||
|
||||
export { leftClick, rightClick };
|
||||
@ -222,6 +222,8 @@ export const useTree = () => {
|
||||
*/
|
||||
const onCheck = async (event: any, treeId: any, treeNode: any) => {
|
||||
console.log(treeNode, 'treeNode')
|
||||
let parentNode = treeNode.getParentNode();
|
||||
|
||||
let params = JSON.parse(treeNode.params)
|
||||
let entityObject
|
||||
if (treeNode.sourceType == 'pressModel') {
|
||||
@ -253,6 +255,41 @@ export const useTree = () => {
|
||||
}
|
||||
TreeApi.updateDirectoryInfo(params2)
|
||||
|
||||
|
||||
|
||||
// 如果当前节点有父节点,检查所有子节点状态
|
||||
if (parentNode) {
|
||||
checkChildNodes(parentNode);
|
||||
}
|
||||
|
||||
// 检查子节点状态,更新父节点
|
||||
function checkChildNodes(parentNode) {
|
||||
var children = parentNode.children;
|
||||
if (!children || children.length === 0) return;
|
||||
|
||||
// 检查是否所有子节点都未被选中
|
||||
var allUnchecked = true;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var childNode = children[i];
|
||||
// 如果有任何一个子节点被选中,则父节点不应被取消
|
||||
if (childNode.isShow) {
|
||||
allUnchecked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有子节点都未被选中,且父节点当前是选中状态,则取消父节点选择
|
||||
if (allUnchecked && parentNode.isShow) {
|
||||
window.treeObj.checkNode(parentNode, false, true);
|
||||
|
||||
// 递归检查上一级父节点
|
||||
var grandParent = parentNode.getParentNode();
|
||||
if (grandParent) {
|
||||
checkChildNodes(grandParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let source_ids = [];
|
||||
// nodes.forEach((item) => {
|
||||
// if (item.isHidden == false) {
|
||||
@ -489,13 +526,13 @@ export const useTree = () => {
|
||||
const initTreeCallBack = () => {
|
||||
if (window.earth) {
|
||||
for (let i = 0; i < zNodes.value.length; i++) {
|
||||
if(zNodes.value[i].sourceType === 'directory') {
|
||||
if (zNodes.value[i].sourceType === 'directory') {
|
||||
continue
|
||||
}
|
||||
//@ts-ignore
|
||||
let params = JSON.parse(zNodes.value[i].params||'{}')
|
||||
let params = JSON.parse(zNodes.value[i].params || '{}')
|
||||
//@ts-ignore
|
||||
let detail = JSON.parse(zNodes.value[i].detail||'{}')
|
||||
let detail = JSON.parse(zNodes.value[i].detail || '{}')
|
||||
if (!params.id) {
|
||||
params.id = zNodes.value[i].id
|
||||
}
|
||||
|
||||
@ -10,6 +10,22 @@ export const useTreeNode = () => {
|
||||
// addToDatabase: addPoint,
|
||||
// allowChildren: false,
|
||||
},
|
||||
linkImage: {
|
||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
||||
// render: renderBaseMarker,
|
||||
// render2d: renderBaseMarker2d,
|
||||
// detailFun: get_detail_point,
|
||||
// addToDatabase: addPoint,
|
||||
// allowChildren: false,
|
||||
},
|
||||
vrImage: {
|
||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
||||
// render: renderBaseMarker,
|
||||
// render2d: renderBaseMarker2d,
|
||||
// detailFun: get_detail_point,
|
||||
// addToDatabase: addPoint,
|
||||
// allowChildren: false,
|
||||
},
|
||||
line: {
|
||||
rightMenus: ['edit', 'del', 'setView', 'resetView']
|
||||
// render: renderBaseMarker,
|
||||
@ -553,6 +569,7 @@ export const useTreeNode = () => {
|
||||
try {
|
||||
arr = nodeType[selectedNodes[0].sourceType].rightMenus
|
||||
} catch (e) {
|
||||
console.log('e',e)
|
||||
arr = []
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
<ProjectionConvert ref="ProjectionConvert"></ProjectionConvert>
|
||||
<GoodsSearchCircle ref="GoodsSearchCircle"></GoodsSearchCircle>
|
||||
<GoodsSearchPolgon ref="GoodsSearchPolgon"></GoodsSearchPolgon>
|
||||
<!-- <selectImg ref="selectImgRef"></selectImg> -->
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -75,9 +76,13 @@ import ProjectionConvert from '../components/propertyBox/ProjectionConvert.vue'
|
||||
import GoodsSearchCircle from '../components/propertyBox/GoodsSearchCircle.vue'
|
||||
import GoodsSearchPolgon from '../components/propertyBox/GoodsSearchPolgon.vue'
|
||||
import flat from '../components/propertyBox/flat.vue'
|
||||
import terrain from '../components/propertyBox/terrain.vue'
|
||||
import { useRightOperate } from '../components/tree/components/hooks/rightOperate'
|
||||
// import selectImg from '../components/selectImg/index.vue'
|
||||
|
||||
import { GisApi } from '@/api/gisApi'
|
||||
|
||||
const { rightMenus } = useRightOperate()
|
||||
const firstMenuRef = ref(null)
|
||||
const bottomMenuRef = ref(null)
|
||||
const eventBus: any = inject('bus')
|
||||
@ -85,9 +90,10 @@ let currentComponent = shallowRef()
|
||||
let dynamicComponentRef = ref()
|
||||
let addStandTextRef = ref()
|
||||
let tree = ref()
|
||||
let selectImgRef = ref()
|
||||
eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
console.log(sourceType, id)
|
||||
if(dynamicComponentRef.value && dynamicComponentRef.value.close) {
|
||||
if (dynamicComponentRef.value && dynamicComponentRef.value.close) {
|
||||
dynamicComponentRef.value.close()
|
||||
}
|
||||
switch (sourceType) {
|
||||
@ -112,6 +118,8 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
case 'point':
|
||||
case 'linkImage':
|
||||
case 'vrImage':
|
||||
currentComponent.value = billboardObject
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
@ -191,16 +199,40 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
|
||||
console.log('cccc', id)
|
||||
dynamicComponentRef.value?.open(id, 'pressModel')
|
||||
break
|
||||
case 'terrain':
|
||||
currentComponent.value = terrain
|
||||
await nextTick()
|
||||
dynamicComponentRef.value?.open(id)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
eventBus.on('openSelectImg', () => {
|
||||
// selectImgRef.value?.open()
|
||||
})
|
||||
eventBus.on('destroyComponent', () => {
|
||||
currentComponent.value = undefined
|
||||
})
|
||||
|
||||
const createEarth = async () => {
|
||||
window.earth = await new YJ.YJEarth('earthContainer')
|
||||
let openLeftClick = await new YJ.Global.openLeftClick(window.earth)
|
||||
let openRightClick = await new YJ.Global.openRightClick(window.earth)
|
||||
YJ.Global.MouseRightMenu(window.earth, true, (text, object) => {
|
||||
console.log(text)
|
||||
switch (text) {
|
||||
case 'rotateAround':
|
||||
YJ.Global.rotateAround(window.earth, object.position)
|
||||
break
|
||||
case 'textBox':
|
||||
break
|
||||
case 'attribute':
|
||||
let node = window.treeObj.getNodeByParam("id", object.id, null);
|
||||
rightMenus.edit.callback(eventBus, node)
|
||||
break
|
||||
}
|
||||
})
|
||||
tree.value.initTreeCallBack()
|
||||
// YJ.Global.setDefaultView(window.earth, {
|
||||
// destination: { lng: 100, lat: 30, alt: 10 },
|
||||
|
||||