Compare commits

...

10 Commits

Author SHA1 Message Date
0e8793f01d 工具 2025-09-10 10:31:32 +08:00
zh
a1f5a61252 提交 2025-09-09 10:06:18 +08:00
zh
47fa66ce6b 合并 2025-09-08 17:26:59 +08:00
zh
50ef8e1f05 合并 2025-09-08 09:10:10 +08:00
zh
6629775367 Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl 2025-09-05 19:45:55 +08:00
zh
41bffc2e83 合并 2025-09-05 19:45:46 +08:00
a33fbb1cbe Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl 2025-09-05 19:42:13 +08:00
39dc98401d 修改 2025-09-05 19:42:09 +08:00
zh
30745547c2 Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl 2025-09-05 19:20:27 +08:00
zh
9f1d2e9e4f 合并 2025-09-05 19:19:12 +08:00
40 changed files with 2153 additions and 212 deletions

86
package-lock.json generated
View File

@ -13,9 +13,11 @@
"@electron-toolkit/utils": "^4.0.0", "@electron-toolkit/utils": "^4.0.0",
"@ztree/ztree_v3": "^3.5.48", "@ztree/ztree_v3": "^3.5.48",
"axios": "^1.11.0", "axios": "^1.11.0",
"clipboard": "^2.0.11",
"dayjs": "^1.11.18",
"echarts": "^6.0.0",
"electron-updater": "^6.3.9", "electron-updater": "^6.3.9",
"element-plus": "^2.10.4", "element-plus": "^2.10.4",
"js-md5": "^0.8.3",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"pinia": "^3.0.3", "pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.4.1", "pinia-plugin-persistedstate": "^4.4.1",
@ -30,7 +32,7 @@
"@electron-toolkit/eslint-config-ts": "^3.0.0", "@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/tsconfig": "^1.0.1", "@electron-toolkit/tsconfig": "^1.0.1",
"@types/jquery": "^3.5.32", "@types/jquery": "^3.5.32",
"@types/node": "^22.16.5", "@types/node": "^22.18.1",
"@types/plist": "^3.0.5", "@types/plist": "^3.0.5",
"@types/verror": "^1.10.11", "@types/verror": "^1.10.11",
"@types/vue-i18n": "^6.1.3", "@types/vue-i18n": "^6.1.3",
@ -2649,9 +2651,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.16.5", "version": "22.18.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.16.5.tgz", "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.18.1.tgz",
"integrity": "sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==", "integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.21.0" "undici-types": "~6.21.0"
@ -4647,6 +4649,17 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/clipboard": {
"version": "2.0.11",
"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
"integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
"license": "MIT",
"dependencies": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"node_modules/cliui": { "node_modules/cliui": {
"version": "8.0.1", "version": "8.0.1",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz",
@ -5196,9 +5209,9 @@
} }
}, },
"node_modules/dayjs": { "node_modules/dayjs": {
"version": "1.11.13", "version": "1.11.18",
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/de-indent": { "node_modules/de-indent": {
@ -5361,6 +5374,12 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"license": "MIT"
},
"node_modules/delegates": { "node_modules/delegates": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz",
@ -5610,6 +5629,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/echarts": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-6.0.0.tgz",
"integrity": "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "2.3.0",
"zrender": "6.0.0"
}
},
"node_modules/ejs": { "node_modules/ejs": {
"version": "3.1.10", "version": "3.1.10",
"resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz", "resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz",
@ -7248,6 +7277,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
"license": "MIT",
"dependencies": {
"delegate": "^3.1.2"
}
},
"node_modules/gopd": { "node_modules/gopd": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
@ -8453,11 +8491,6 @@
"dev": true, "dev": true,
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
@ -10986,6 +11019,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/select": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==",
"license": "MIT"
},
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
@ -12243,6 +12282,12 @@
"node": ">= 10.0.0" "node": ">= 10.0.0"
} }
}, },
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"license": "MIT"
},
"node_modules/tiny-typed-emitter": { "node_modules/tiny-typed-emitter": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmmirror.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", "resolved": "https://registry.npmmirror.com/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
@ -12461,6 +12506,12 @@
"typescript": ">=4.8.4" "typescript": ">=4.8.4"
} }
}, },
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"license": "0BSD"
},
"node_modules/type-check": { "node_modules/type-check": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
@ -13886,6 +13937,15 @@
"engines": { "engines": {
"node": ">= 10" "node": ">= 10"
} }
},
"node_modules/zrender": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-6.0.0.tgz",
"integrity": "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==",
"license": "BSD-3-Clause",
"dependencies": {
"tslib": "2.3.0"
}
} }
} }
} }

View File

@ -25,6 +25,8 @@
"@electron-toolkit/utils": "^4.0.0", "@electron-toolkit/utils": "^4.0.0",
"@ztree/ztree_v3": "^3.5.48", "@ztree/ztree_v3": "^3.5.48",
"axios": "^1.11.0", "axios": "^1.11.0",
"clipboard": "^2.0.11",
"dayjs": "^1.11.18",
"echarts": "^6.0.0", "echarts": "^6.0.0",
"electron-updater": "^6.3.9", "electron-updater": "^6.3.9",
"element-plus": "^2.10.4", "element-plus": "^2.10.4",
@ -42,7 +44,7 @@
"@electron-toolkit/eslint-config-ts": "^3.0.0", "@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/tsconfig": "^1.0.1", "@electron-toolkit/tsconfig": "^1.0.1",
"@types/jquery": "^3.5.32", "@types/jquery": "^3.5.32",
"@types/node": "^22.16.5", "@types/node": "^22.18.1",
"@types/plist": "^3.0.5", "@types/plist": "^3.0.5",
"@types/verror": "^1.10.11", "@types/verror": "^1.10.11",
"@types/vue-i18n": "^6.1.3", "@types/vue-i18n": "^6.1.3",

View File

@ -4,6 +4,8 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/earth.png?asset' import icon from '../../resources/earth.png?asset'
import fs from 'fs' import fs from 'fs'
const { exec } = require('child_process');
// 开发环境路径处理 - 确保添加正确的file协议 // 开发环境路径处理 - 确保添加正确的file协议
const devSplashPath = path.resolve( const devSplashPath = path.resolve(
app.getAppPath(), app.getAppPath(),

View File

@ -25,7 +25,6 @@ declare module 'vue' {
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs'] ElTabs: typeof import('element-plus/es')['ElTabs']
ElTag: typeof import('element-plus/es')['ElTag']
ElUpload: typeof import('element-plus/es')['ElUpload'] ElUpload: typeof import('element-plus/es')['ElUpload']
Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default'] Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default']
Pagination: typeof import('./src/components/Pagination/index.vue')['default'] Pagination: typeof import('./src/components/Pagination/index.vue')['default']

View File

@ -49,7 +49,7 @@ body {
background: var(--color-background); background: var(--color-background);
line-height: 1.6; line-height: 1.6;
font-family: font-family:
Inter, SourceHanSans,
-apple-system, -apple-system,
BlinkMacSystemFont, BlinkMacSystemFont,
'Segoe UI', 'Segoe UI',

View File

@ -32,10 +32,15 @@
@font-face { @font-face {
font-family: 'sy-boldface'; font-family: 'sy-boldface';
src: url('../fonts/sy-boldface.otf') format('opentype'); src: url('../iconfont/sy-boldface.otf') format('opentype');
} }
@font-face { @font-face {
font-family: 'Ali-mother-counts-bold'; font-family: 'Ali-mother-counts-bold';
src: url('../fonts/Ali-mother-counts-bold.ttf') format('truetype'); src: url('../iconfont/Ali-mother-counts-bold.ttf') format('truetype');
}
@font-face {
font-family: 'SourceHanSans';
src: url('../iconfont/SourceHanSansCN-Medium.otf') format('opentype');
} }

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12" height="12" viewBox="0 0 12 12" fill="none">
<path d="M3.06995 0.0336822C3.30345 -0.0134909 3.72175 0.0203715 4.04432 0.0203715L8.80938 0.0203715C9.40915 0.0203715 10.1307 -0.0457695 10.6647 0.0603036C11.1902 0.1647 11.5443 0.463472 11.7725 0.858946C12.0226 1.29218 11.9994 1.8259 11.9994 2.52278L11.9994 10.1232C11.9994 11.3662 11.3459 12 10.0774 12L3.41699 12C3.05145 12 2.7978 11.9615 2.78966 11.6805C2.77859 11.2992 3.13767 11.3345 3.59051 11.3345L9.62358 11.3345C9.9666 11.3345 10.3532 11.3732 10.5979 11.3078C10.9435 11.2156 11.2516 10.9028 11.3187 10.5225C11.3785 10.1841 11.3321 9.80816 11.3321 9.41772L11.3321 2.70913C11.3321 2.34708 11.3626 1.95707 11.3321 1.59103C11.2915 1.1051 10.9141 0.772719 10.5312 0.699218C10.2419 0.643685 9.88335 0.685907 9.54349 0.685907L3.55046 0.685907C3.25907 0.685907 2.87412 0.72524 2.803 0.446314C2.74999 0.238375 2.86113 0.0758638 3.06995 0.0336822ZM4.9653 7.34125L2.00215 7.34125C1.65943 7.34125 1.32269 7.37425 1.04113 7.31463C0.477442 7.19527 0.00413877 6.69706 2.77496e-05 6.02349C-0.00437695 5.30309 0.516243 4.73537 1.24135 4.67911C1.82735 4.63364 2.47369 4.67911 3.11 4.67911L4.9653 4.67911C5.01246 4.16292 4.79863 2.94146 5.29899 2.94872C5.53703 2.95217 5.7177 3.11918 5.87293 3.24155C6.7027 3.89572 7.45568 4.47287 8.31552 5.11836C8.57959 5.3166 9.11366 5.62915 9.10303 6.05011C9.09247 6.46816 8.55953 6.78468 8.30218 6.98186C7.46283 7.62495 6.69288 8.19646 5.84623 8.83205C5.69609 8.94478 5.46648 9.11088 5.2456 9.05833C4.76802 8.9447 5.0393 7.88096 4.9653 7.34125Z" fill="#FFFFFF" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,138 @@
export function processBase64Images(base64Data1, base64Data2, callback) {
if (!base64Data1 || !base64Data2) {
alert("请输入两个Base64图像数据");
return;
}
// 创建Image对象并加载第一个Base64图像
const img1 = new Image();
img1.onload = function () {
// 创建Image对象并加载第二个Base64图像
const img2 = new Image();
img2.onload = function () {
// 计算拼接后的Canvas尺寸这里示例为水平拼接垂直拼接可调整计算方式
const totalWidth = img1.width + img2.width;
const maxHeight = Math.max(img1.height, img2.height);
console.log("maxHeight", maxHeight);
const resultCanvas = document.createElement("canvas");
// 设置结果Canvas的尺寸
resultCanvas.width = totalWidth;
resultCanvas.height = maxHeight;
// 获取Canvas绘图上下文
const ctx = resultCanvas.getContext("2d");
// 绘制第一个图像(左上角开始)
ctx.drawImage(img1, 0, 0);
// 绘制第二个图像(第一个图像右侧)
ctx.drawImage(img2, img1.width, 0);
// 获取拼接后的Base64结果默认为PNG格式可指定其他格式如JPEG
const resultBase64Data = resultCanvas.toDataURL("image/png");
callback(resultBase64Data);
console.log("图像拼接完成Base64结果已生成");
};
img2.src = base64Data1;
};
img1.src = base64Data2;
}
/**
* 拼接两个Base64图像并返回新的Base64
* @param {string} base641 第一个Base64图像数据
* @param {number} width1 第一个图像要截取的宽度
* @param {string} base642 第二个Base64图像数据
* @param {number} width2 第二个图像要截取的宽度
* @param {string} [format='image/png'] 输出图像格式
* @param {number} [quality=1.0] 输出图像质量(0-1),仅对支持的格式有效
* @returns {Promise<string>} 拼接后的Base64图像数据
*/
export function combineBase64Images(
base641,
width1,
base642,
width2,
format = "image/png",
quality = 1.0
) {
return new Promise((resolve, reject) => {
// 创建canvas元素
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// 设置canvas宽度和高度
canvas.width = width1 + width2;
canvas.height = 0; // 高度将在图像加载后确定
// 创建图像对象
const img1 = new Image();
const img2 = new Image();
// 错误处理
function handleError(error) {
reject(new Error(`图像处理错误: ${error.message}`));
}
// 监听两个图像都加载完成
let loadedCount = 0;
function checkAllLoaded() {
loadedCount++;
if (loadedCount === 2) {
drawAndResolve();
}
}
// 图像1加载事件
img1.onload = function () {
checkAllLoaded();
};
// 图像2加载事件
img2.onload = function () {
checkAllLoaded();
};
// 图像加载错误事件
img1.onerror = img2.onerror = handleError;
// 加载图像
img1.src = base641;
img2.src = base642;
// 绘制图像并解析为Base64
function drawAndResolve() {
try {
// 确定canvas高度为两个图像高度的最大值
const height1 = img1.height;
const height2 = img2.height;
canvas.height = Math.max(height1, height2);
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制第一个图像的左侧部分 (从左往右截取width1)
ctx.drawImage(img1, 0, 0, width1, height1, 0, 0, width1, canvas.height);
// 绘制第二个图像的右侧部分 (从右往左截取width2)
// 计算在原图上的截取起点 (从右侧开始)
const sourceX = img2.width - width2;
ctx.drawImage(
img2,
sourceX,
0,
width2,
height2,
width1,
0,
width2,
canvas.height
);
// 将canvas内容转换为Base64
const resultBase64 = canvas.toDataURL(format, quality);
resolve(resultBase64);
} catch (error) {
handleError(error);
}
}
});
}

View File

@ -1,63 +0,0 @@
import { ipcRenderer, remote } from "electron";
import Vue from "vue";
import { Loading } from "element-ui";
let bus = new Vue();
// let bus = window.$root_home;
let $sendChanel = (chanel, arg = {}) => {
// let bus = new Vue();
bus.$emit(chanel, arg);
};
let $recvChanel = (chanel, cb) => {
bus.$on(chanel, cb);
};
let $offChanel = (chanel, cb) => {
bus.$off(chanel);
};
let $removeChanel = (chanel) => {
bus.$off(chanel);
};
let $sendElectronChanel = (chanel, arg = null) => {
ipcRenderer.send(chanel, arg);
};
let $removeElectronChanel = (chanel, cb) => {
ipcRenderer.removeListener(chanel, cb);
};
let $recvElectronChanel = (chanel, cb) => {
ipcRenderer.once(chanel, cb);
};
let $changeComponentShow = (selector, state, styleStr = false) => {
$(selector).css({ display: state ? "block" : "none" });
if (styleStr) {
console.log(123);
let str = styleStr.split(":");
if (str[0] === "top") $(selector).css({ top: str[1] });
if (str[0] === "z-index") $(selector).css({ zIndex: str[1] });
}
};
let openLoading = (
text = "拼命加载中...",
option = {
fullscreen: true,
background: "rgba(0,0,0,0.63)",
lock: true,
// spinner: 'el-icon-loading'
}
) => {
option.text = text;
let loadingInstance = Loading.service(option);
return loadingInstance;
};
let $remote = remote;
export {
openLoading,
$sendElectronChanel,
$removeElectronChanel,
$recvElectronChanel,
$sendChanel,
$recvChanel,
$offChanel,
$removeChanel,
$changeComponentShow,
$remote,
};

View File

@ -1,3 +1,4 @@
const { ipcRenderer } = require('electron')
export const $changeComponentShow = (selector: any, state: any, styleStr: any = false) => { export const $changeComponentShow = (selector: any, state: any, styleStr: any = false) => {
$(selector).css({ visibility: state ? 'visible' : 'hidden' }) $(selector).css({ visibility: state ? 'visible' : 'hidden' })
if (styleStr) { if (styleStr) {
@ -17,3 +18,13 @@ export const $changeComponentPop = (selector: any, state: any, styleStr: any = f
if (str[0] === 'z-index') $(selector).css({ zIndex: str[1] }) if (str[0] === 'z-index') $(selector).css({ zIndex: str[1] })
} }
} }
export const $sendElectronChanel = (chanel: any, arg: any = null) => {
console.log('发送给electron', chanel, arg);
ipcRenderer.send(chanel, arg);
};
export const $recvElectronChanel = (chanel: any, cb: any) => {
console.log('接收来自electron', chanel);
ipcRenderer.once(chanel, cb);
};

View File

@ -1,13 +1,8 @@
<template> <template>
<div class="bottomMenuBox zIndex9"> <div class="bottomMenuBox zIndex9">
<div class="animate__animated bottomMenu"> <div class="animate__animated bottomMenu">
<div <div class="bottom_box" v-for="(item, i) of bottomMenuList" :key="i" :title="t('bottomMenu.' + item.sourceType)"
class="bottom_box" @click="addMarker(item)">
v-for="(item, i) of bottomMenuList"
:key="i"
:title="t('bottomMenu.' + item.sourceType)"
@click="addMarker(item)"
>
<svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon> <svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon>
<div class="span"> <div class="span">
{{ t('bottomMenu.' + item.sourceType) }} {{ t('bottomMenu.' + item.sourceType) }}
@ -23,6 +18,8 @@ import { useI18n } from 'vue-i18n'
import { inject } from 'vue' import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
import { useTreeNode } from '../tree/hooks/treeNode'
const { cusAddNodes } = useTreeNode()
const { t } = useI18n() const { t } = useI18n()
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
@ -84,6 +81,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'point', sourceType: 'point',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -92,6 +90,7 @@ const bottomMenuList = ref([
params: options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -120,6 +119,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'line', sourceType: 'line',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -128,6 +128,7 @@ const bottomMenuList = ref([
params: options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -154,6 +155,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'curve', sourceType: 'curve',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -162,6 +164,7 @@ const bottomMenuList = ref([
params: options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -194,6 +197,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'panel', sourceType: 'panel',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -202,8 +206,8 @@ const bottomMenuList = ref([
params: options params: options
} }
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -211,7 +215,38 @@ const bottomMenuList = ref([
sourceName: '圆标注', sourceName: '圆标注',
key: 'DrawCircle', key: 'DrawCircle',
sourceType: 'circle', sourceType: 'circle',
className: 'public' className: 'public',
fun: () => {
let Draw = new YJ.Draw.DrawCircle(window.earth)
Draw.start(async (a, opt) => {
let id = new YJ.Tools().randomString()
let name = '圆'
let options: any = await initMapData('circle', {
id: id,
name: name,
center: opt.center, radius: opt.radius
})
delete options.host
console.log('options', options)
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: "circle",
// isShow: 1,
parentId: (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
// "treeIndex": 0,
params: options
}
// eventBus.emit("openDialog", 'circle');
// TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
})
}
}, },
{ {
sourceName: '矩形', sourceName: '矩形',
@ -242,6 +277,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'rectangle', sourceType: 'rectangle',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -252,6 +288,7 @@ const bottomMenuList = ref([
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -286,6 +323,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'rendezvous', sourceType: 'rendezvous',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -296,6 +334,7 @@ const bottomMenuList = ref([
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -330,6 +369,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'attackArrow', sourceType: 'attackArrow',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -340,6 +380,7 @@ const bottomMenuList = ref([
console.log(params) console.log(params)
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
}, },
@ -375,6 +416,7 @@ const bottomMenuList = ref([
id: id, id: id,
sourceName: name, sourceName: name,
sourceType: 'pincerArrow', sourceType: 'pincerArrow',
// isShow: 1,
parentId: parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1] selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id ? selectedNodes[selectedNodes.length - 1].id
@ -384,6 +426,7 @@ const bottomMenuList = ref([
} }
// eventBus.emit("openDialog", 'panel'); // eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
} }
@ -485,7 +528,7 @@ const addMarker = (item: any) => {
transform: scale(0.8); transform: scale(0.8);
} }
> .span { >.span {
color: #fff; color: #fff;
font-family: 黑体; font-family: 黑体;
font-size: 1rem; font-size: 1rem;

View File

@ -39,8 +39,8 @@ import { bus } from '@/utils/bus'
import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue' import leftSideSecond from '@/views/components/leftSide/leftSideSecond.vue'
const { t } = useI18n() const { t } = useI18n()
const eventBus = inject('bus') const eventBus: any = inject('bus')
const menuList = ref([ const menuList: any = ref([
// 方案推演 // 方案推演
{ {
name: 'situation', name: 'situation',
@ -128,28 +128,28 @@ const menuList = ref([
// fun: this.showSecondMenu, // fun: this.showSecondMenu,
key: 'tool', key: 'tool',
children: [ children: [
// 'routePlan', 'routePlan',
// 'clearRoute', 'clearRoute',
// 'graffiti', 'graffiti',
// // stopGraffiti: "结束涂鸦", // stopGraffiti: "结束涂鸦",
// 'clearGraffiti', 'clearGraffiti',
// 'path', 'path',
// 'coorLocation', 'coorLocation',
// 'mouseLocation', 'mouseLocation',
// 'annotationAggregation', 'annotationAggregation',
// 'annotation', 'annotation',
// 'screenShot', 'screenShot',
// 'highQuality', 'highQuality',
// 'videoRecord', 'videoRecord',
// 'pressModel', 'pressModel',
// 'terrainDig', 'terrainDig',
// 'tilesetClipping', 'tilesetClipping',
// 'clearTilesetClipping', 'clearTilesetClipping',
// 'projConvert', 'projConvert',
// 'projectionConvert', 'projectionConvert',
// 'gdbImport', 'gdbImport',
// 'circleStatistics', 'circleStatistics',
// 'polygonStatistics' 'polygonStatistics'
] ]
}, },
{ {

View File

@ -22,9 +22,14 @@ import { ref, reactive, getCurrentInstance } from 'vue'
import { useTreeNode } from '../tree/hooks/treeNode' import { useTreeNode } from '../tree/hooks/treeNode'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import { renderMethods } from '../tree/hooks/renderTreeNode' import { renderMethods } from '../tree/hooks/renderTreeNode'
import { processBase64Images, combineBase64Images } from '@/utils/HighDefinitionScreenshot'
import { $sendElectronChanel, $recvElectronChanel } from '@/utils/communication'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import fs from 'fs'
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { t } = useI18n() const { t } = useI18n()
const { findParentId, findTreeIndex } = useTreeNode() const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
const obj = ref(null) const obj = ref(null)
const isclick = ref(false) const isclick = ref(false)
const eventBus = inject('bus') const eventBus = inject('bus')
@ -42,6 +47,13 @@ eventBus.on('graffitiObj', (data) => {
graffitiObjArr.push(data) graffitiObjArr.push(data)
}) })
const methodMap = { const methodMap = {
// 轨迹运动
trajectoryMotion: () => {
// let draw = new YJ.Draw.DrawPolyline(window.earth)
// draw.start((err, positions) => {
// if (positions.length > 1) {}
// })
},
// 电子围墙 // 电子围墙
electronicFence: () => { electronicFence: () => {
let draw = new YJ.Draw.DrawPolyline(window.earth) let draw = new YJ.Draw.DrawPolyline(window.earth)
@ -51,7 +63,8 @@ const methodMap = {
positions.forEach((item) => { positions.forEach((item) => {
if (item.alt < alt) alt = item.alt if (item.alt < alt) alt = item.alt
}) })
let id = proxy.$md5(new Date().getTime() + '围墙') // let id = new YJ.Tools().randomString()
let id = 'aaa'
let params = { let params = {
sourceName: '电子围墙', sourceName: '电子围墙',
id, id,
@ -71,10 +84,11 @@ const methodMap = {
// 渲染电子围墙 // 渲染电子围墙
renderMethods.renderWallStereoscopic(params) renderMethods.renderWallStereoscopic(params)
// 存入数据库 // 存入数据库
let res = TreeApi.addOtherSource(params) // let res = TreeApi.addOtherSource(params)
console.log('addOtherSource', res) // console.log('addOtherSource', res)
// 上树 // 上树
cusAddNodes(window.treeObj, params.parentId, [params]) cusAddNodes(window.treeObj, params.parentId, [params])
eventBus.emit('openDialog', 'wallStereoscopic')
} }
}) })
}, },
@ -214,14 +228,70 @@ const methodMap = {
//卷帘对比 //卷帘对比
annotation() { annotation() {
clickChange.annotation = !clickChange.annotation clickChange.annotation = !clickChange.annotation
// if (clickChange.annotation) { if (clickChange.annotation) {
// YJ.Global.splitScreen.on(window.earth) YJ.Global.splitScreen.on(window.earth)
// } else { } else {
// YJ.Global.splitScreen.off() YJ.Global.splitScreen.off()
// } }
}, },
//屏幕截图 //屏幕截图
screenShot() {}, async screenShot() {
function downloadScreen(res) {
let base64 = res.replace(/^data:image\/\w+;base64,/, '')
console.log('base64', base64)
let dataBuffer = new Buffer(base64, 'base64')
$sendElectronChanel('saveFile', {
title: '保存图片',
filename: dayjs().format('YYYYMMDDHHmmss') + '截图',
filters: [{ name: '保存图片', extensions: ['jpg'] }]
})
$recvElectronChanel('selectedFileItem', (e, path) => {
console.log('path', fs.writeFile)
fs.writeFile(path, dataBuffer, (res) => {
console.log(res)
})
})
}
if (window.splitScreen || window.multiViewportMode) {
let res = ''
let res2 = ''
let sdk
if (window.splitScreen) {
sdk = YJ.Global.splitScreen.getSdk()
} else {
sdk = YJ.Global.multiViewportMode.getSdk()
}
await new YJ.Global.ScreenShot(sdk.sdkD, (data) => {
res = data
})
await new YJ.Global.ScreenShot(sdk.sdkP, (data) => {
res2 = data
})
if (window.multiViewportMode) {
processBase64Images(res, res2, (mergedBase64) => {
downloadScreen(mergedBase64)
// window.multiViewportMode = false;
})
} else {
let doms = document.querySelectorAll('.cesium-widget')
let leftWidth = doms[0].offsetWidth
let rightWidth = doms[1].offsetWidth
combineBase64Images(res2, leftWidth, res, rightWidth)
.then((result) => {
downloadScreen(result)
// window.splitScreen = false;
})
.catch((err) => console.error('拼接失败:', err))
}
} else {
let res = ''
await new YJ.Global.ScreenShot(window.earth, (data) => {
res = data
})
downloadScreen(res)
}
},
//高清出图 //高清出图
highQuality() { highQuality() {
// eventBus.emit('screenShotDialog') // eventBus.emit('screenShotDialog')
@ -230,27 +300,130 @@ const methodMap = {
//视频录制 //视频录制
videoRecord() { videoRecord() {
clickChange.videoRecord = !clickChange.videoRecord clickChange.videoRecord = !clickChange.videoRecord
let time = 3
this.$changeComponentShow('#secondMenu', false)
// const onKeyDown = (e) => {
// if (e.keyCode === 27) {
// item.status = !item.status;
// $sendElectronChanel("endRecoder");
// document.removeEventListener("keydown", onKeyDown);
// }
// };
if (clickChange.videoRecord) {
// document.addEventListener("keydown", onKeyDown);
let loading = $root_home.openLoading(time, {
background: 'rgba(0,0,0,0)',
fullscreen: false,
customClass: 'timer'
})
let timer = ''
const p = document.createElement('p')
p.style.color = '#fff'
p.innerHTML = '再次点击录制结束'
document.getElementsByClassName('el-loading-spinner')[0].appendChild(p)
let func = () => {
loading.setText(time--)
if (time == -1) {
clearInterval(timer)
loading.close()
console.log('开始了')
p.remove()
$sendElectronChanel('startRecoder')
}
}
func()
timer = setInterval(func, 1000)
} else {
$sendElectronChanel('endRecoder')
// document.removeEventListener("keydown", onKeyDown);
}
}, },
//压模 //压模
pressModel() {}, pressModel() {},
//地形开挖 //地形开挖
terrainDig() { terrainDig() {
// if (window.checkAuthIsValid) {
// new YJ.Analysis.TerrainExcavation(window.Earth1);
eventBus.emit('terrainExcavationDialog') eventBus.emit('terrainExcavationDialog')
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
}, },
//剖切 //剖切
tilesetClipping() {}, tilesetClipping() {
// if (window.checkAuthIsValid) {
let selectedNode = window.treeObj.getSelectedNodes()
if (selectedNode.length < 1) {
ElMessage({
message: '请在图层指挥舱选中对应模型进行操作',
type: 'warning'
})
return
}
if (!(selectedNode[0].sourceType === 'tileset' || selectedNode[0].sourceType === 'bim')) {
ElMessage({
message: '选中的节点不能进行剖切',
type: 'warning'
})
return
}
let tileset = window.earth.entityMap.get(selectedNode[0].id)
let draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, pos) => {
let section = new YJ.Analysis.Section(window.earth, tileset.entity, {
positions: pos
})
// _entityMap.set(selectedNode.source_id + 'pouqie', section)
})
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//删除剖切 //删除剖切
clearTilesetClipping() {}, clearTilesetClipping() {
YJ.Analysis.ClearSection()
},
//度分秒 //度分秒
projConvert() {}, projConvert() {
eventBus.emit('projConvertDialog')
},
//投影转换 //投影转换
projectionConvert() {}, projectionConvert() {
eventBus.emit('ProjectionConvertDialog')
},
//GDB导入 //GDB导入
gdbImport() {}, gdbImport() {},
//圆形统计 //圆形统计
circleStatistics() {}, circleStatistics() {
// if (window.checkAuthIsValid) {
eventBus.emit('goodsSearchCircleDialog')
// } else {
// this.$message({
// message: '您没有该功能的权限',
// type: 'warning'
// })
// }
},
//多边形统计 //多边形统计
polygonStatistics() {} polygonStatistics() {
// if (window.checkAuthIsValid) {
eventBus.emit('goodsSearchPolgonDialog')
// } else {
// this.$message({
// message: "您没有该功能的权限",
// type: "warning",
// });
// }
}
} }
const handleClick = (value = 'projectionDistanceMeasure') => { const handleClick = (value = 'projectionDistanceMeasure') => {

View File

@ -0,0 +1,336 @@
<template>
<Dialog ref="baseDialog" :title="title+'属性'" left="180px" top="100px" className="polygon" :closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row" style="align-items: flex-start;">
<div class="col">
<span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name">
</div>
<div class="col" style="flex: 0 0 60%;">
<div class="row">
<div class="col input-select-unit-box">
<span class="label" style="margin-right: 0px;">投影面积:</span>
<input class="input input-text" readonly type="text" v-model="area">
<el-select v-model="areaUnit">
<el-option label="平方米" value="m2"></el-option>
<el-option label="平方千米" value="km2"></el-option>
<el-option label="亩" value="mu"></el-option>
<el-option label="公顷" value="ha"></el-option>
</el-select>
</div>
</div>
</div>
</div>
</div>
<div class="div-item">
<div class="row">
<el-tabs v-model="activeName">
<el-tab-pane label="属性信息" name="1">
<attribute :entityOptions="entityOptions"></attribute>
</el-tab-pane>
<el-tab-pane label="空间信息" name="2">
<div class="row">
<div class="col height-mode-box">
<span class="label" style="flex: 0 0 56px;">高度模式</span>
<el-select class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px"
v-model="heightMode" @change="heightModeChange" placeholder="请选择">
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key">
</el-option>
</el-select>
</div>
<div class="col">
<span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box" :class="{ 'disabled': heightMode == 2 }">
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height">
<span class="unit">m</span>
<span class="arrow"></span>
</div>
<button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm"
:disabled="heightMode == 2">应用</button>
</div>
</div>
<div class="row">
<div class="table spatial-info-table">
<div class="table-head">
<div class="tr">
<div class="th"></div>
<div class="th">经度X</div>
<div class="th">纬度Y</div>
<div class="th">高度Z</div>
</div>
</div>
<div class="table-body">
<div class="tr">
<div class="td">圆心坐标</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, 1, 'lng')">
<input class="input" @blur="inputBlurCallBack($event, 1, 'lng', 8)" type="number"
v-model="entityOptions.center.lng" min="-180" max="180" v-if="activeTd.index == 1 && activeTd.name == 'lng'">
<span style="pointer-events: none;" v-else>{{ entityOptions.center.lng.toFixed(8) }}</span>
</div>
<div class="td lat align-center" @dblclick="inputDblclick($event, 1, 'lat')">
<input class="input" @blur="inputBlurCallBack($event, 1, 'lat', 8)" type="number"
v-model="entityOptions.center.lat" min="-180" max="180" v-if="activeTd.index == 1 && activeTd.name == 'lat'">
<span style="pointer-events: none;" v-else>{{ entityOptions.center.lat.toFixed(8) }}</span>
</div>
<div class="td alt align-center" @dblclick="inputDblclick($event, 1, 'alt')">
<input class="input" @blur="inputBlurCallBack($event, 1, 'alt', 2)" type="number"
v-model="entityOptions.height" min="-9999999" max="999999999"
v-if="activeTd.index == 1 && activeTd.name == 'alt'">
<span style="pointer-events: none;" v-else>{{ entityOptions.height.toFixed(2) }}</span>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="面风格" name="3">
<div class="row">
<div class="col">
<span class="label">面颜色</span>
<div class="color" ref="colorRef"></div>
</div>
<div class="col">
<span class="label">描边颜色</span>
<div class="lineColor" ref="lineColorRef"></div>
</div>
<div class="col">
<span class="label">描边宽度</span>
<div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="0" max="99" v-model="entityOptions.lineWidth">
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="标签风格" name="4">
<labelStyle :type="title" :entityOptions="entityOptions"></labelStyle>
</el-tab-pane>
</el-tabs>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<div style="position: absolute; left: 24px; display: flex;">
<button @click="nodeEdit"><svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use>
</svg>二次编辑</button>
<button style="margin-left: 10px;" @click="translate"><svg class="icon-py">
<use xlink:href="#yj-icon-py"></use>
</svg>平移</button>
</div>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { inject } from "vue";
import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue'
import attribute from './attribute.vue'
import labelStyle from './labelStyle.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const title = ref('圆')
const baseDialog: any = ref(null);
const eventBus: any = inject("bus");
const options = ref({});
const colorRef = ref(null)
const lineColorRef = ref(null)
eventBus.on("openPolygonEdit", () => {
baseDialog.value?.open()
});
const area = ref(0)
const areaUnit = ref('m2')
const height = ref(10)
const heightModeData = ref([
{
name: '海拔高度',
value: '海拔高度',
key: 0
},
{
name: '相对地表',
value: '相对地表',
key: 1
},
{
name: '依附模型',
value: '依附模型',
key: 2
}
])
const activeName = ref('1')
const activeTd = ref({
index: -1,
name: ''
})
const center = ref({})
const heightMode = ref(0)
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const open = async (id: any, type: any) => {
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
heightMode.value = entityOptions.value.heightMode
area.value = entityOptions.value.areaByMeter
center.value = structuredClone(that.options.center)
that.areaChangeCallBack = () => {
switch (areaUnit.value) {
case 'm2'://平方米
area.value = entityOptions.value.areaByMeter
break
case 'km2'://平方千米
area.value = Number((entityOptions.value.areaByMeter / 1000000).toFixed(8))
break
case 'mu'://亩
area.value = Number(
(entityOptions.value.areaByMeter / 666.6666667).toFixed(4)
)
break
case 'ha'://公顷
area.value = Number((entityOptions.value.areaByMeter / 10000).toFixed(6))
break
default:
area.value = entityOptions.value.areaByMeter
}
}
heightModeChange(heightMode.value)
baseDialog.value?.open()
await nextTick()
let colorPicker = new window.YJColorPicker({
el: colorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.color = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
let linecolorPicker = new window.YJColorPicker({
el: lineColorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.lineColor,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.lineColor = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.lineColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const heightModeChange = (val) => {
that.heightMode = heightMode.value
}
const heightConfirm = () => {
if (entityOptions.value.operate.positionEditing) {
that.positionEditing = false
entityOptions.value.height = Number((entityOptions.value.height + Number(height.value)).toFixed(2))
}
else {
that.closeNodeEdit(this)
that.heightMode = that.heightMode
setTimeout(() => {
entityOptions.value.height = Number((entityOptions.value.height + Number(height.value)).toFixed(2))
}, 100);
}
}
const inputDblclick = async (event, i, anme) => {
if(heightMode.value == 2) {
return
}
activeTd.value = {
index: i,
name: anme
}
await nextTick()
let inputElm = event.target.getElementsByClassName('input')[0]
if (inputElm) {
inputElm.focus()
}
}
const inputBlurCallBack = (event, i, name, digit = 2) => {
activeTd.value = {
index: -1,
name: ''
}
}
const translate = () => {
that.openPositionEditing(() => {
entityOptions.value.options.center = structuredClone(that.options.center)
})
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.closeNodeEdit()
entityOptions.value.reset()
eventBus.emit("destroyComponent")
}
const nodeEdit = () => {
that.nodeEdit((e, center, areaByMeter) => {
entityOptions.value.options.center = structuredClone(center)
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
delete params.host
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0,
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
watch(
() => areaUnit.value,
(val) => {
if ((entityOptions.value.areaByMeter || entityOptions.value.areaByMeter == 0) && that) {
that.areaChangeCallBack()
}
},
{ immediate: true }
);
defineExpose({
open
})
</script>
<style scoped lang="scss"></style>

View File

@ -69,8 +69,8 @@ import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
const viewPointHeight: any = ref(1.8) const viewPointHeight: any = ref(1.8)
const precision: any = ref(20) const precision: any = ref(20)
@ -92,7 +92,7 @@ const viewPointHeightChange = () => {
visibility.viewPointHeights = viewPointHeight.value visibility.viewPointHeights = viewPointHeight.value
} }
const viewPointHeightInput = () => { const viewPointHeightInput = () => {
let dom = document.getElementById('viewPointHeight') let dom: any = document.getElementById('viewPointHeight')
if (viewPointHeight.value < dom.min * 1) { if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1 viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) { } else if (viewPointHeight.value > dom.max * 1) {

View File

@ -13,7 +13,7 @@
<div class="row" style="align-items: flex-start"> <div class="row" style="align-items: flex-start">
<div class="col" style="flex: 0 0 120px"> <div class="col" style="flex: 0 0 120px">
<span class="label">等高线</span> <span class="label">等高线</span>
<input class="btn-switch show" type="checkbox" /> <input class="btn-switch show" type="checkbox" v-model="show" />
</div> </div>
</div> </div>
</div> </div>
@ -145,6 +145,7 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<button @click="sure">确定</button>
<button @click="close">取消</button> <button @click="close">取消</button>
</template> </template>
</Dialog> </Dialog>
@ -155,19 +156,27 @@ import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var show: any = ref(true)
eventBus.on('contourDialog', () => { eventBus.on('contourDialog', () => {
baseDialog.value?.open() baseDialog.value?.open()
setTimeout(() => { setTimeout(() => {
YJ.Global.Contour(window.earth) YJ.Global.Contour(window.earth)
}) })
}) })
const closeCallBack = (e) => {} const closeCallBack = (e) => {
YJ.Global.ContourReset()
show.value = true
}
const close = (e) => { const close = (e) => {
baseDialog.value?.close() baseDialog.value?.close()
} }
const sure = (e) => {
YJ.Global.ContourStartDraw(window.earth, show.value)
baseDialog.value?.close()
}
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -5,6 +5,7 @@
title="坐标定位" title="坐标定位"
left="180px" left="180px"
top="100px" top="100px"
width="418px"
:closeCallback="closeCallBack" :closeCallback="closeCallBack"
> >
<template #content> <template #content>
@ -117,8 +118,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
const activeName = ref('first') const activeName = ref('first')
@ -135,6 +136,7 @@ eventBus.on('coorLocationDialog', () => {
baseDialog.value?.open() baseDialog.value?.open()
}) })
// @ts-ignore (define in dts)
const handleClick = (tab: TabsPaneContext, event: Event) => { const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event) console.log(tab, event)
longitude.value = null longitude.value = null
@ -160,9 +162,13 @@ const flyto = (e) => {
}) })
break break
case 'second': case 'second':
// @ts-ignore (define in dts)
var lng = Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 var lng = Math.abs(longitude.value) + Math.abs(lngMin.value) / 60
// @ts-ignore (define in dts)
var lat = Math.abs(latitude.value) + Math.abs(latMin.value) / 60 var lat = Math.abs(latitude.value) + Math.abs(latMin.value) / 60
// @ts-ignore (define in dts)
lng = longitude.value < 0 ? -lng : lng lng = longitude.value < 0 ? -lng : lng
// @ts-ignore (define in dts)
lat = latitude.value < 0 ? -lat : lat lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 } var position = { lng, lat, alt: 100 }
@ -172,11 +178,15 @@ const flyto = (e) => {
break break
case 'third': case 'third':
var lng = var lng =
// @ts-ignore (define in dts)
Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 + Math.abs(lngSec.value) / 3600 Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 + Math.abs(lngSec.value) / 3600
var lat = var lat =
// @ts-ignore (define in dts)
Math.abs(latitude.value) + Math.abs(latMin.value) / 60 + Math.abs(latSec.value) / 3600 Math.abs(latitude.value) + Math.abs(latMin.value) / 60 + Math.abs(latSec.value) / 3600
// @ts-ignore (define in dts)
lng = longitude.value < 0 ? -lng : lng lng = longitude.value < 0 ? -lng : lng
// @ts-ignore (define in dts)
lat = latitude.value < 0 ? -lat : lat lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 } var position = { lng, lat, alt: 100 }

View File

@ -112,8 +112,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var height: any = ref(70) var height: any = ref(70)
var precision: any = ref(125) var precision: any = ref(125)
@ -135,7 +135,7 @@ eventBus.on('cutFillDialog', () => {
}) })
const heightInput = () => { const heightInput = () => {
let dom = document.getElementById('height') let dom: any = document.getElementById('height')
if (height.value < dom.min * 1) { if (height.value < dom.min * 1) {
height.value = dom.min * 1 height.value = dom.min * 1
} else if (height.value > dom.max * 1) { } else if (height.value > dom.max * 1) {

View File

@ -1,4 +1,4 @@
<template> <!-- <template>
<Dialog <Dialog
ref="baseDialog" ref="baseDialog"
class="fly-roam" class="fly-roam"
@ -121,8 +121,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var show: any = ref(false) var show: any = ref(false)
var flyRoam: any = reactive([]) var flyRoam: any = reactive([])
@ -154,4 +154,4 @@ const close = (e) => {
} }
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style> -->

View File

@ -0,0 +1,340 @@
<template>
<Dialog
v-if="show"
ref="baseDialog"
title="物质统计"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<div id="goodSearchEchart" style="width: 100%; height: 100%"></div>
</template>
<template #footer>
<button>绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import { nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const shpTotalDict: any = reactive({
shlwz_jzzp: '救灾帐篷',
mb: '棉被',
mymdy: '棉衣、棉大衣',
mjb: '毛巾被',
mt: '毛毯',
dgnsd: '睡袋',
zdc: '折叠床',
jycs: '简易厕所',
xpct: '橡皮船(艇)',
cfz: '冲锋舟',
jsc: '救生船',
jsy: '救生衣',
jsq: '救生圈',
bzd: '编织袋',
md: '麻袋',
csb: '抽水泵',
fdj: '发电机',
yjd: '应急灯',
jzzp: '救灾帐篷',
jzyb: '救灾衣被',
jygj: '救援工具'
})
var draw: any = reactive([])
var show: any = ref(false)
eventBus.on('goodsSearchCircleDialog', () => {
console.log('kkkkkk')
// baseDialog.value?.open()
draw = new YJ.Draw.DrawCircle(window.earth)
draw.start((err, positions) => {
console.log('err, positions', err, positions)
if (!err && positions.center.lng) {
show.value = true
let nodes = booleanOverlaps(positions)
console.log('goodsSearchCircle', nodes)
renderCanvas(nodes)
}
})
})
function booleanOverlaps(positions1, flag = 'circle') {
let cross = undefined
function set3Array(positions) {
let arr = []
positions.forEach((item) => {
arr.push([item.lng, item.lat])
})
arr.push(arr[0])
return arr
}
let getNode = (types) => {
let treeObj = window.treeObj
let res = []
types.forEach((type) => {
let nodes = treeObj.getNodesByParam('sourceType', type, null)
// console.log("nodes",nodes)
res = res.concat(nodes)
})
return res
}
//绘制的区域
// console.log("[set3Array(positions1)]", [set3Array(positions1)])
// 获取物资处(特定的标注类型)
let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
console.log('allNodes', allNodes)
let itemInArea = [] //区域内的类型符合的标注
for (let i = 0; i < allNodes.length; i++) {
let item = allNodes[i]
let getAllItemInArea = (lng, lat) => {
if (flag == 'circle') {
let { center, radius } = positions1
let distance = new YJ.Tools().randomString(center, { lng, lat })
distance < radius && itemInArea.push(item)
} else {
let polygon1 = turf.polygon([set3Array(positions1)])
let pt = turf.point([lng, lat])
turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
}
}
console.log(item, item.sourceType, 'ooooo')
switch (item.sourceType) {
case 'point':
case 'vr':
case 'picture':
let params = JSON.parse(item.params)
console.log('params', params)
let lng = params.position.lng
let lat = params.position.lat
getAllItemInArea(lng, lat)
break
case 'Feature':
if (item.detail.geometry.type == 'Point') {
lng = item.detail.geometry.coordinates[0]
lat = item.detail.geometry.coordinates[1]
getAllItemInArea(lng, lat)
}
break
}
}
return itemInArea
}
function renderCanvas(nodes) {
console.log('nodes', nodes)
let x: any = []
let y: any = []
nodes.forEach((item) => {
// shp物资统计
if (item.sourceType == 'Feature') {
let obj = JSON.parse(JSON.stringify(item.detail.properties))
for (const key in obj) {
let name = key
if (shpTotalDict[key]) {
name = shpTotalDict[key]
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === name)
if (index !== -1) {
y[index] = y[index] + Number(obj[key])
} else {
x.push(name)
y.push(Number(obj[key]))
}
}
}
}
let params = JSON.parse(item.params)
if (params.attribute && params.attribute.goods) {
let goods = params.attribute.goods.content
console.log('goods', goods)
if (goods.length) {
// $root_home_index.goodSearchDialog = false;
goods.forEach((good) => {
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === good.name)
if (index !== -1) {
y[index] = y[index] + Number(good.cnt)
} else {
x.push(good.name)
y.push(Number(good.cnt))
}
})
}
}
})
console.log('x,y')
console.log(x)
console.log(y)
let notZeroX = []
let notZeroY = []
for (let i = 0; i < y.length; i++) {
if (y[i] != 0) {
notZeroX.push(x[i])
notZeroY.push(y[i])
}
}
console.log(notZeroX)
console.log(notZeroY)
x = notZeroX
y = notZeroY
if (!x.length) show.value = false
if (show.value) {
nextTick(() => {
let option = {
grid: {
top: '20%',
left: '5%',
right: '5%',
bottom: '8%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
},
formatter(params) {
var data = ''
for (var i = 0; i < params.length; i++) {
if (params[i].seriesName == '随访率') {
data += params[i].seriesName + ': ' + params[i].value + '%'
} else {
data += params[i].seriesName + ': ' + params[i].value + '<br/>'
}
}
return data
}
},
legend: {
data: ['总量'],
top: '5%',
left: '5%',
right: '5%',
bottom: '5%',
textStyle: {
color: '#fff'
}
},
xAxis: {
// type: "category",
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
width: 40, //将内容的宽度固定
overflow: 'truncate', //超出的部分截断
truncate: '...', //截断的部分用...代替
rotate: 30,
interval: 0,
textStyle: {
color: '#fff' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: '(数量)',
nameTextStyle: {
color: '#fff'
},
splitLine: {
show: true,
lineStyle: {
color: '#eeeeee'
}
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#fff'
}
}
},
{
type: 'value',
gridIndex: 0,
min: 50,
max: 100,
splitNumber: 8,
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
}
}
}
],
series: [
{
name: '数量',
type: 'bar',
label: {
show: true,
position: 'top'
},
barWidth: 15,
itemStyle: {
normal: {
color: '#fdcb6c'
}
}
}
]
}
var dom = document.getElementById('goodSearchEchart')
var myChart = (window as any).echarts.init(dom)
option.xAxis.data = x
option.series[0].data = y
myChart.setOption(option)
})
} else {
ElMessage({
message: '该区域没有物资',
type: 'warning'
})
}
}
const closeCallBack = (e) => {}
</script>
<style scoped lang="scss"></style>

View File

@ -0,0 +1,328 @@
<template>
<Dialog
v-if="show"
ref="baseDialog"
title="物质统计"
left="180px"
top="100px"
:closeCallback="closeCallBack"
>
<template #content>
<div id="goodSearchEchart2" style="width: 100%; height: 100%"></div>
</template>
<template #footer>
<button>绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import { nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
const shpTotalDict: any = reactive({
shlwz_jzzp: '救灾帐篷',
mb: '棉被',
mymdy: '棉衣、棉大衣',
mjb: '毛巾被',
mt: '毛毯',
dgnsd: '睡袋',
zdc: '折叠床',
jycs: '简易厕所',
xpct: '橡皮船(艇)',
cfz: '冲锋舟',
jsc: '救生船',
jsy: '救生衣',
jsq: '救生圈',
bzd: '编织袋',
md: '麻袋',
csb: '抽水泵',
fdj: '发电机',
yjd: '应急灯',
jzzp: '救灾帐篷',
jzyb: '救灾衣被',
jygj: '救援工具'
})
var draw: any = reactive([])
var show: any = ref(false)
eventBus.on('goodsSearchPolgonDialog', () => {
draw = new YJ.Draw.DrawPolygon(window.earth)
draw.start((err, params) => {
if (!err && params.length > 2) {
show.value = true
let nodes = booleanOverlaps(params, 'polygon')
renderCanvas(nodes)
}
})
})
function booleanOverlaps(positions1, flag = 'circle') {
let cross = undefined
function set3Array(positions) {
let arr = []
positions.forEach((item) => {
arr.push([item.lng, item.lat])
})
arr.push(arr[0])
return arr
}
let getNode = (types) => {
let treeObj = window.treeObj
let res = []
types.forEach((type) => {
let nodes = treeObj.getNodesByParam('sourceType', type, null)
res = res.concat(nodes)
})
return res
}
//绘制的区域
// 获取物资处(特定的标注类型)
let allNodes = getNode(['point', 'vr', 'picture', 'Feature'])
let itemInArea = [] //区域内的类型符合的标注
for (let i = 0; i < allNodes.length; i++) {
let item = allNodes[i]
let getAllItemInArea = (lng, lat) => {
if (flag == 'circle') {
let { center, radius } = positions1
let distance = new YJ.Tools().randomString(center, { lng, lat })
distance < radius && itemInArea.push(item)
} else {
let polygon1 = turf.polygon([set3Array(positions1)])
let pt = turf.point([lng, lat])
turf.booleanPointInPolygon(pt, polygon1) && itemInArea.push(item)
}
}
switch (item.sourceType) {
case 'point':
case 'vr':
case 'picture':
let params = JSON.parse(item.params)
let lng = params.position.lng
let lat = params.position.lat
getAllItemInArea(lng, lat)
break
case 'Feature':
if (item.detail.geometry.type == 'Point') {
lng = item.detail.geometry.coordinates[0]
lat = item.detail.geometry.coordinates[1]
getAllItemInArea(lng, lat)
}
break
}
}
return itemInArea
}
function renderCanvas(nodes) {
let x: any = []
let y: any = []
nodes.forEach((item) => {
// shp物资统计
if (item.sourceType == 'Feature') {
let obj = JSON.parse(JSON.stringify(item.detail.properties))
for (const key in obj) {
let name = key
if (shpTotalDict[key]) {
name = shpTotalDict[key]
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === name)
if (index !== -1) {
y[index] = y[index] + Number(obj[key])
} else {
x.push(name)
y.push(Number(obj[key]))
}
}
}
}
let params = JSON.parse(item.params)
if (params.attribute && params.attribute.goods) {
let goods = params.attribute.goods.content
if (goods.length) {
// $root_home_index.goodSearchDialog = false;
goods.forEach((good) => {
// 把相同名称的物资数量相加,名称相同时,累加数据
let index = x.findIndex((item) => item === good.name)
if (index !== -1) {
y[index] = y[index] + Number(good.cnt)
} else {
x.push(good.name)
y.push(Number(good.cnt))
}
})
}
}
})
console.log('x,y')
console.log(x)
console.log(y)
let notZeroX = []
let notZeroY = []
for (let i = 0; i < y.length; i++) {
if (y[i] != 0) {
notZeroX.push(x[i])
notZeroY.push(y[i])
}
}
console.log(notZeroX)
console.log(notZeroY)
x = notZeroX
y = notZeroY
if (!x.length) show.value = false
if (show.value) {
nextTick(() => {
let option = {
grid: {
top: '20%',
left: '5%',
right: '5%',
bottom: '8%',
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
},
formatter(params) {
var data = ''
for (var i = 0; i < params.length; i++) {
if (params[i].seriesName == '随访率') {
data += params[i].seriesName + ': ' + params[i].value + '%'
} else {
data += params[i].seriesName + ': ' + params[i].value + '<br/>'
}
}
return data
}
},
legend: {
data: ['总量'],
top: '5%',
left: '5%',
right: '5%',
bottom: '5%',
textStyle: {
color: '#fff'
}
},
xAxis: {
// type: "category",
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
width: 40, //将内容的宽度固定
overflow: 'truncate', //超出的部分截断
truncate: '...', //截断的部分用...代替
rotate: 30,
interval: 0,
textStyle: {
color: '#fff' //X轴文字颜色
}
}
},
yAxis: [
{
type: 'value',
name: '(数量)',
nameTextStyle: {
color: '#fff'
},
splitLine: {
show: true,
lineStyle: {
color: '#eeeeee'
}
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: true,
textStyle: {
color: '#fff'
}
}
},
{
type: 'value',
gridIndex: 0,
min: 50,
max: 100,
splitNumber: 8,
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
},
splitArea: {
show: false,
areaStyle: {
color: ['rgba(250,250,250,0.0)', 'rgba(250,250,250,0.05)']
}
}
}
],
series: [
{
name: '数量',
type: 'bar',
label: {
show: true,
position: 'top'
},
barWidth: 15,
itemStyle: {
normal: {
color: '#fdcb6c'
}
}
}
]
}
var dom = document.getElementById('goodSearchEchart2')
var myChart = (window as any).echarts.init(dom)
option.xAxis.data = x
option.series[0].data = y
myChart.setOption(option)
})
} else {
ElMessage({
message: '该区域没有物资',
type: 'warning'
})
}
}
const closeCallBack = (e) => {}
</script>
<style scoped lang="scss"></style>

View File

@ -48,8 +48,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var width: any = ref(1) var width: any = ref(1)
var graffiti: any = reactive([]) var graffiti: any = reactive([])
@ -59,12 +59,12 @@ eventBus.on('graffitiDialog', () => {
graffiti = new YJ.Obj.Graffiti(window.earth, { graffiti = new YJ.Obj.Graffiti(window.earth, {
width: width.value width: width.value
}) })
}, 0) }, 10)
}) })
const closeCallBack = (e) => {} const closeCallBack = (e) => {}
const widthInput = () => { const widthInput = () => {
let dom = document.getElementById('width') let dom: any = document.getElementById('width')
if (width.value < dom.min * 1) { if (width.value < dom.min * 1) {
width.value = dom.min * 1 width.value = dom.min * 1
} else if (width.value > dom.max * 1) { } else if (width.value > dom.max * 1) {

View File

@ -25,8 +25,8 @@ import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
//属性 //属性
var profile: any = reactive([]) var profile: any = reactive([])
var echartsObject: any = reactive({}) var echartsObject: any = reactive({})
@ -50,6 +50,7 @@ function close() {
baseDialog.value?.close() baseDialog.value?.close()
} }
const draw = (e) => { const draw = (e) => {
// @ts-ignore (define in dts)
initEcharts() initEcharts()
profile.reDraw() profile.reDraw()
} }
@ -68,12 +69,14 @@ function initEcharts(points) {
continue continue
} }
const curData = [element.distance.toFixed(2), element.position.height.toFixed(2)] const curData = [element.distance.toFixed(2), element.position.height.toFixed(2)]
// @ts-ignore (define in dts)
datas.push(curData) datas.push(curData)
const curCoords = [element.position.lng, element.position.lat] const curCoords = [element.position.lng, element.position.lat]
// @ts-ignore (define in dts)
coords.push(curCoords) coords.push(curCoords)
} }
const ele = document.getElementsByClassName('profile-echarts')[0] const ele = document.getElementsByClassName('profile-echarts')[0]
echartsObject = echarts.init(ele) echartsObject = (window as any).echarts.init(ele)
option = { option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@ -81,7 +84,7 @@ function initEcharts(points) {
align: 'left' align: 'left'
}, },
formatter(params) { formatter(params) {
const xy = coords[params[0].dataIndex] const xy: any = coords[params[0].dataIndex]
const tipData = params[0]['data'] const tipData = params[0]['data']
profile.formatter(xy, tipData) profile.formatter(xy, tipData)
return ( return (
@ -174,7 +177,7 @@ function initEcharts(points) {
}, },
areaStyle: { areaStyle: {
normal: { normal: {
color: new echarts.graphic.LinearGradient( color: new (window as any).echarts.graphic.LinearGradient(
0, 0,
0, 0,
0, 0,
@ -222,7 +225,7 @@ function initEcharts(points) {
} }
} else { } else {
const ele = document.getElementsByClassName('profile-echarts')[0] const ele = document.getElementsByClassName('profile-echarts')[0]
echartsObject = echarts.init(ele) echartsObject = (window as any).echarts.init(ele)
option = { option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
@ -305,7 +308,7 @@ function initEcharts(points) {
}, },
areaStyle: { areaStyle: {
normal: { normal: {
color: new echarts.graphic.LinearGradient( color: new (window as any).echarts.graphic.LinearGradient(
0, 0,
0, 0,
0, 0,

View File

@ -0,0 +1,283 @@
<template>
<Dialog
ref="baseDialog"
class="proj-convert"
title="度分秒格式转换"
left="180px"
top="100px"
width="515px"
:closeCallback="closeCallBack"
>
<template #content v-if="status1">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col input-select-box">
<span class="label" style="flex: 0 0 60px">输入格式</span>
<div class="input-select"></div>
</div>
</div>
</div>
<div class="div-item item" data-type="0">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px"></span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55">例如116.6°, 39.9°</span>
</p>
<div class="row">
<div class="col">
<span class="label" style="flex: auto">经度</span>
<input class="input lng" type="number" min="-180" max="180" value="0" title="" />
</div>
<div class="col" style="margin: 0">
<span class="label">纬度</span>
<input class="input lat" type="number" min="-90" max="90" value="0" title="" />
</div>
<div class="col" style="flex: 0 0 24px">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px"> </button>
</div>
</div>
</div>
<div class="div-item item" data-type="1">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分</span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
>例如95°10.1702', 49°12.4015'</span
>
</p>
<div class="row">
<div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px">
<span class="label">经度</span>
<input
class="input lng-dm-d"
style="flex: 1"
type="number"
min="-180"
max="180"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dm-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span>
</div>
<div class="row">
<span class="label">纬度</span>
<input
class="input lat-dm-d"
style="flex: 1"
type="number"
min="-90"
max="90"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dm-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span>
</div>
</div>
<div class="col" style="flex: 0 0 24px; margin: 0">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer; position: relative; left: -30px"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px"> </button>
</div>
</div>
</div>
<div class="div-item item" data-type="2">
<span class="custom-divider"></span>
<p style="font-size: 16px; padding-bottom: 6px; margin-top: 10px; margin-bottom: 5px">
<span style="margin-right: 10px">度分秒</span>
<span style="font-size: 12px; margin-bottom: 5px; color: #f16c55"
>例如11°18'54.37", 39°13'46.57"</span
>
</p>
<div class="row">
<div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px">
<span class="label">经度</span>
<input
class="input lng-dms-d"
style="flex: 1"
type="number"
min="-180"
max="180"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
<input
class="input lng-dms-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
<input
class="input lng-dms-s"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
<span class="top-line"></span>
</div>
<div class="row">
<span class="label">纬度</span>
<input
class="input lat-dms-d"
style="flex: 1"
type="number"
min="-90"
max="90"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">度</span>
<input
class="input lat-dms-m"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">分</span>
<input
class="input lat-dms-s"
style="flex: 1"
type="number"
min="0"
max="60"
value="0"
title=""
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px">秒</span>
<span class="bottom-line"></span>
</div>
</div>
<div class="col" style="flex: 0 0 24px; margin: 0">
<i
class="icon-copy-box"
title="复制"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="cursor: pointer; position: relative; left: -30px"
>
<svg class="icon-copy" style="margin: 4px; margin-bottom: 0px">
<use xlink:href="#yj-icon-copy"></use>
</svg>
</i>
<button class="convert" style="margin-left: 10px">转 换</button>
</div>
</div>
</div>
<span class="custom-divider" style="order: 10; margin-top: 12px"></span>
</template>
<template #footer>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import Clipboard from 'clipboard'
import { ElMessage } from 'element-plus'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var status1: any = ref(false)
var tools: any = reactive([])
eventBus.on('projConvertDialog', () => {
baseDialog.value?.open()
if (status1.value) {
reset()
status1.value = false
}
status1.value = !status1.value
setTimeout(() => {
tools = new YJ.Tools(window.earth)
tools.projConvert(status1.value, () => {
status1.value = false
})
}, 100)
})
const closeCallBack = (e) => {
status1.value = false
}
const reset = () => {
let contentElm = document
.getElementsByClassName('proj-convert')[0]
.getElementsByClassName('content')[0]
contentElm.getElementsByClassName('lng-dms-d')[0].value = null
contentElm.getElementsByClassName('lng-dms-m')[0].value = null
contentElm.getElementsByClassName('lng-dms-s')[0].value = null
contentElm.getElementsByClassName('lat-dms-d')[0].value = null
contentElm.getElementsByClassName('lat-dms-m')[0].value = null
contentElm.getElementsByClassName('lat-dms-s')[0].value = null
contentElm.getElementsByClassName('lng')[0].value = null
contentElm.getElementsByClassName('lat')[0].value = null
}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss">
::v-deep .content > div {
display: flex !important;
flex-direction: column !important;
}
</style>

View File

@ -0,0 +1,171 @@
<template>
<Dialog
ref="baseDialog"
class="projection-convert"
title="投影转换"
left="180px"
top="100px"
width="634px"
:closeCallback="closeCallBack"
>
<template #content v-if="status1">
<span class="custom-divider"></span>
<div style="width: 585px; display: flex">
<div class="row left" style="flex: 1; margin-bottom: 0">
<div
style="
margin: 10px 0;
flex: 1;
display: flex;
align-items: center;
flex: 1;
justify-content: space-between;
"
>
<span class="lable-left-line">源坐标</span>
<button class="btn pick" style="margin-left: 15px">
<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>坐标拾取
</button>
<button
class="btn sourceCopy"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="margin-left: 5px"
>
<svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
</button>
</div>
<div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">椭圆基准</span>
<div class="datalist_left"></div>
</div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">经度(x)</span>
<input class="input left-x" type="number" title="" />
</div>
<div style="display: flex; margin-bottom: 10px; align-items: center">
<span class="label" style="flex: 0 0 60px">纬度(y)</span>
<input class="input left-y" type="number" title="" />
</div>
</div>
</div>
<div
style="
display: flex;
flex-direction: column;
justify-content: center;
margin: 28px 15px 0 15px;
"
>
<button class="btn convert">
<svg-icon name="turn" :size="11" color="rgba(255, 255, 255, 1)"></svg-icon>
转换
</button>
</div>
<div class="row right" style="flex: 1; margin-bottom: 0">
<div
style="
margin: 10px 0;
height: 32px;
display: flex;
align-items: center;
flex: 1;
justify-content: space-between;
"
>
<span class="lable-left-line">目标坐标</span>
<button
class="btn copy"
data-clipboard-action="copy"
data-clipboard-target=".input"
style="margin-left: 20px"
>
<svg class="icon-copy"><use xlink:href="#yj-icon-copy"></use></svg>复制
</button>
</div>
<div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">椭圆基准</span>
<div class="datalist_right"></div>
</div>
<div style="display: flex; margin-bottom: 12px; align-items: center">
<span class="label" style="flex: 0 0 60px">经度(x)</span>
<input class="input right-x" readonly="readonly" />
</div>
<div style="display: flex; margin-bottom: 10px; align-items: center">
<span class="label" style="flex: 0 0 60px">纬度(y)</span>
<input class="input right-y" readonly="readonly" />
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import Clipboard from 'clipboard'
import { ElMessage } from 'element-plus'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var status1: any = ref(false)
var tools: any = reactive([])
eventBus.on('ProjectionConvertDialog', () => {
baseDialog.value?.open()
if (status1.value) {
reset()
status1.value = false
tools && tools.projectionConvert(status1.value, () => {})
}
status1.value = !status1.value
setTimeout(() => {
tools = new YJ.Tools(window.earth)
tools.projectionConvert(status1.value, () => {
status1.value = false
})
}, 100)
})
const closeCallBack = (e) => {
status1.value = false
tools && tools.projectionConvert(status1.value, () => {})
}
const reset = () => {
let contentElm = document
.getElementsByClassName('projection-convert')[0]
.getElementsByClassName('content')[0]
contentElm.getElementsByClassName('left-x')[0].value = null
contentElm.getElementsByClassName('left-y')[0].value = null
contentElm.getElementsByClassName('right-x')[0].value = null
contentElm.getElementsByClassName('right-y')[0].value = null
}
const close = (e) => {
baseDialog.value?.close()
}
</script>
<style scoped lang="scss">
::v-deep .content > div {
display: flex !important;
flex-direction: column !important;
}
::v-deep .content .cy_datalist input {
background: rgba(var(--color-sdk-base-rgb), 0.2) !important;
border: unset;
}
::v-deep .content input[type='number'] {
font-size: 16px !important;
// font-weight: 700 !important;
color: var(--color-sdk-auxiliary-public) !important;
}
</style>

View File

@ -29,8 +29,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
//属性 //属性
var startLng: any = ref(null) var startLng: any = ref(null)

View File

@ -128,8 +128,8 @@ import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var selectType: any = ref('first') var selectType: any = ref('first')
var scale: any = ref(1) var scale: any = ref(1)
var radio: any = ref('1:500') var radio: any = ref('1:500')

View File

@ -184,8 +184,8 @@ import { ref, reactive, onMounted } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
// 属性 // 属性
var minWaterLevel: any = ref(0) var minWaterLevel: any = ref(0)
var maxWaterLevel: any = ref(0) var maxWaterLevel: any = ref(0)
@ -261,7 +261,7 @@ function analog() {
} }
function minWaterLevelInput() { function minWaterLevelInput() {
let dom = document.getElementById('minWaterLevel') let dom: any = document.getElementById('minWaterLevel')
if (minWaterLevel.value != '.') { if (minWaterLevel.value != '.') {
if (minWaterLevel.value < dom.min * 1) { if (minWaterLevel.value < dom.min * 1) {
minWaterLevel.value = dom.min * 1 minWaterLevel.value = dom.min * 1
@ -277,7 +277,7 @@ function minWaterLevelInput() {
} }
} }
function maxWaterLevelInput() { function maxWaterLevelInput() {
let dom = document.getElementById('maxWaterLevel') let dom: any = document.getElementById('maxWaterLevel')
if (minWaterLevel.value != '.') { if (minWaterLevel.value != '.') {
if (maxWaterLevel.value < dom.min * 1) { if (maxWaterLevel.value < dom.min * 1) {
maxWaterLevel.value = dom.min * 1 maxWaterLevel.value = dom.min * 1
@ -299,7 +299,7 @@ function maxWaterLevelInput() {
} }
} }
function areaInput() { function areaInput() {
let dom = document.getElementById('area') let dom: any = document.getElementById('area')
if (minWaterLevel.value != '.') { if (minWaterLevel.value != '.') {
if (area.value < dom.min * 1) { if (area.value < dom.min * 1) {
area.value = dom.min * 1 area.value = dom.min * 1
@ -315,7 +315,7 @@ function areaInput() {
} }
} }
function waterVolumeInput() { function waterVolumeInput() {
let dom = document.getElementById('waterVolume') let dom: any = document.getElementById('waterVolume')
if (waterVolume.value < dom.min * 1) { if (waterVolume.value < dom.min * 1) {
waterVolume.value = dom.min * 1 waterVolume.value = dom.min * 1
} else if (waterVolume.value > dom.max * 1) { } else if (waterVolume.value > dom.max * 1) {
@ -331,7 +331,7 @@ function waterVolumeInput() {
} }
} }
function risingSpeedInput() { function risingSpeedInput() {
let dom = document.getElementById('risingSpeed') let dom: any = document.getElementById('risingSpeed')
if (risingSpeed.value != '.') { if (risingSpeed.value != '.') {
if (risingSpeed.value < dom.min * 1) { if (risingSpeed.value < dom.min * 1) {
risingSpeed.value = dom.min * 1 risingSpeed.value = dom.min * 1

View File

@ -43,7 +43,7 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<button @click="close">取消</button> <button @click="close">关闭</button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -53,8 +53,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
var height: any = ref(10) var height: any = ref(10)
@ -62,7 +62,7 @@ var excavation: any = reactive([])
eventBus.on('terrainExcavationDialog', () => { eventBus.on('terrainExcavationDialog', () => {
baseDialog.value?.open() baseDialog.value?.open()
excavation = new YJ.Analysis.TerrainExcavation(this.sdk, { height: 10 }) excavation = new (window as any).YJ.Analysis.TerrainExcavation(window.earth, { height: 10 })
}) })
const changeHeight = () => { const changeHeight = () => {
@ -76,7 +76,9 @@ const heightInput = () => {
height.value = dom.max * 1 height.value = dom.max * 1
} }
} }
const closeCallBack = (e) => {} const closeCallBack = (e) => {
height.value = 10
}
const close = (e) => { const close = (e) => {
baseDialog.value?.close() baseDialog.value?.close()
} }

View File

@ -87,8 +87,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
const viewPointHeight: any = ref(1.8) const viewPointHeight: any = ref(1.8)
var horizontalViewAngle: any = ref(90) var horizontalViewAngle: any = ref(90)
@ -98,13 +98,13 @@ var timeout: any = reactive([])
eventBus.on('viewShedDialog', () => { eventBus.on('viewShedDialog', () => {
baseDialog.value?.open() baseDialog.value?.open()
viewShed && viewShed.destroy && viewShed.destroy() viewShed && viewShed.destroy && viewShed.destroy()
viewShed = new YJ.Analysis.ViewShed(window.earth) viewShed = new (window as any).YJ.Analysis.ViewShed((window as any).earth)
setTimeout(() => { setTimeout(() => {
let contentElm = document.getElementsByClassName('view-shed')[0] let contentElm = document.getElementsByClassName('view-shed')[0]
let e_horizontalViewAngle = contentElm.querySelector("input[name='horizontalViewAngle']") let e_horizontalViewAngle:any = contentElm.querySelector("input[name='horizontalViewAngle']")
let rangeNodeActive = contentElm.getElementsByClassName('range-node-active')[0] let rangeNodeActive:any = contentElm.getElementsByClassName('range-node-active')[0]
let rangeNodeActiveText = rangeNodeActive.getElementsByClassName('range-node-active-text')[0] let rangeNodeActiveText = rangeNodeActive.getElementsByClassName('range-node-active-text')[0]
let rangeProcess = contentElm.getElementsByClassName('range-process')[0] let rangeProcess:any = contentElm.getElementsByClassName('range-process')[0]
let percentage = (horizontalViewAngle.value / 180) * 100 let percentage = (horizontalViewAngle.value / 180) * 100
rangeNodeActive.style.left = percentage + '%' rangeNodeActive.style.left = percentage + '%'
rangeProcess.style.width = percentage + '%' rangeProcess.style.width = percentage + '%'
@ -113,13 +113,13 @@ eventBus.on('viewShedDialog', () => {
e_horizontalViewAngle.removeEventListener('change', changeFun) e_horizontalViewAngle.removeEventListener('change', changeFun)
e_horizontalViewAngle.addEventListener('input', inputFun) e_horizontalViewAngle.addEventListener('input', inputFun)
e_horizontalViewAngle.addEventListener('change', changeFun) e_horizontalViewAngle.addEventListener('change', changeFun)
}) }, 10)
}) })
function inputFun() { function inputFun() {
let contentElm = document.getElementsByClassName('view-shed')[0] let contentElm = document.getElementsByClassName('view-shed')[0]
let rangeNodeActive = contentElm.getElementsByClassName('range-node-active')[0] let rangeNodeActive:any = contentElm.getElementsByClassName('range-node-active')[0]
let rangeNodeActiveText = rangeNodeActive.getElementsByClassName('range-node-active-text')[0] let rangeNodeActiveText:any = rangeNodeActive.getElementsByClassName('range-node-active-text')[0]
let rangeProcess = contentElm.getElementsByClassName('range-process')[0] let rangeProcess:any = contentElm.getElementsByClassName('range-process')[0]
let percentage = (horizontalViewAngle.value / 180) * 100 let percentage = (horizontalViewAngle.value / 180) * 100
rangeNodeActive.style.left = percentage + '%' rangeNodeActive.style.left = percentage + '%'
rangeProcess.style.width = percentage + '%' rangeProcess.style.width = percentage + '%'
@ -138,7 +138,7 @@ const closeCallBack = (e) => {
horizontalViewAngle.value = 90 horizontalViewAngle.value = 90
} }
function viewPointHeightInput(e) { function viewPointHeightInput(e) {
let dom = document.getElementById('viewPointHeight') let dom:any = document.getElementById('viewPointHeight')
if (viewPointHeight.value != '.') { if (viewPointHeight.value != '.') {
if (viewPointHeight.value < dom.min * 1) { if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1 viewPointHeight.value = dom.min * 1

View File

@ -43,8 +43,8 @@ import { ref, reactive } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog = ref(null) const baseDialog: any = ref(null)
const eventBus = inject('bus') const eventBus: any = inject('bus')
const viewPointHeight: any = ref(1.8) const viewPointHeight: any = ref(1.8)
var visibility: any = reactive([]) var visibility: any = reactive([])
eventBus.on('analysisDialog', () => { eventBus.on('analysisDialog', () => {
@ -53,7 +53,7 @@ eventBus.on('analysisDialog', () => {
const clangeViewPointHeight = () => {} const clangeViewPointHeight = () => {}
const viewPointHeightInput = () => { const viewPointHeightInput = () => {
let dom = document.getElementById('viewPointHeight') let dom: any = document.getElementById('viewPointHeight')
if (viewPointHeight.value < dom.min * 1) { if (viewPointHeight.value < dom.min * 1) {
viewPointHeight.value = dom.min * 1 viewPointHeight.value = dom.min * 1
} else if (viewPointHeight.value > dom.max * 1) { } else if (viewPointHeight.value > dom.max * 1) {
@ -61,16 +61,16 @@ const viewPointHeightInput = () => {
} }
} }
const closeCallBack = (e) => { const closeCallBack = (e) => {
viewPointHeight.value = 1.8 viewPointHeight.value = 1.8;
YJ.Measure.SetMeasureStatus(false) (window as any).YJ.Measure.SetMeasureStatus(false)
// visibility && visibility.end() // visibility && visibility.end()
} }
const draw = (e) => { const draw = (e) => {
visibility && visibility.end && visibility.end() visibility && visibility.end && visibility.end()
visibility = new YJ.Analysis.Visibility(window.earth, { viewPointHeight: viewPointHeight.value }) visibility = new YJ.Analysis.Visibility(window.earth, { viewPointHeight: viewPointHeight.value })
// visibility.create(this) // visibility.create(this)
!window.analysisArr && (window.analysisArr = []) !(window as any).analysisArr && ((window as any).analysisArr = []);
window.analysisArr.push(visibility) (window as any).analysisArr.push(visibility);
baseDialog.value?.close() baseDialog.value?.close()
} }
</script> </script>

View File

@ -15,6 +15,9 @@ import { inject } from 'vue'
import { TreeApi } from '@/api/tree' import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { initMapData } from '../tree/initMapData' import { initMapData } from '../tree/initMapData'
import { useTreeNode } from '../tree/hooks/treeNode'
const { cusAddNodes } = useTreeNode()
const baseDialog: any = ref(null) const baseDialog: any = ref(null)
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
@ -37,10 +40,12 @@ const confirm = () => {
let id = new YJ.Tools().randomString() let id = new YJ.Tools().randomString()
let options: any = await initMapData('groundText', { let options: any = await initMapData('groundText', {
id: id, id: id,
name: name, text: name,
positions: positions positions: positions
}) })
delete options.host delete options.host
delete options.positions
console.log('options', options)
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
id: id, id: id,
@ -54,6 +59,7 @@ const confirm = () => {
params: options params: options
} }
TreeApi.addOtherSource(params) TreeApi.addOtherSource(params)
cusAddNodes(window.treeObj, params.parentId, [params])
}) })
} }
defineExpose({ defineExpose({

View File

@ -41,19 +41,20 @@ const confirm = () => {
positions: positions positions: positions
}) })
delete options.host delete options.host
let selectedNodes = window.treeObj.getSelectedNodes() console.log('options', options)
let params = { // let selectedNodes = window.treeObj.getSelectedNodes()
id: id, // let params = {
sourceName: name, // id: id,
sourceType: 'standText', // sourceName: name,
parentId: // sourceType: 'standText',
selectedNodes && selectedNodes[selectedNodes.length - 1] // parentId:
? selectedNodes[selectedNodes.length - 1].id // selectedNodes && selectedNodes[selectedNodes.length - 1]
: undefined, // ? selectedNodes[selectedNodes.length - 1].id
// "treeIndex": 0, // : undefined,
params: options // // "treeIndex": 0,
} // params: options
TreeApi.addOtherSource(params) // }
// TreeApi.addOtherSource(params)
}) })
} }
defineExpose({ defineExpose({

View File

@ -102,6 +102,7 @@ let originalOptions: any
let that: any let that: any
const colorRef = ref(null) const colorRef = ref(null)
const open = async (id: any) => { const open = async (id: any) => {
console.log('id', id)
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
entityOptions.value = that entityOptions.value = that
@ -131,12 +132,12 @@ const confirm = () => {
delete params.name delete params.name
let params2 = { let params2 = {
"id": params.id, "id": params.id,
"sourceName": params.name, "sourceName": params.text,
"params": params, "params": params,
"isShow": params.show ? 1 : 0, "isShow": params.show ? 1 : 0,
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) }) cusUpdateNode({ "id": params.id, "sourceName": params.text, "params": JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()

View File

@ -61,6 +61,7 @@ let originalOptions: any
let that: any let that: any
const colorRef = ref(null) const colorRef = ref(null)
const open = async (id: any) => { const open = async (id: any) => {
id = (window as any).standTextid
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
entityOptions.value = that entityOptions.value = that

View File

@ -28,6 +28,7 @@ export const useRightOperate = () => {
const editNode = (eventBus) => { const editNode = (eventBus) => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
if (selectNodes && selectNodes[selectNodes.length - 1]) { if (selectNodes && selectNodes[selectNodes.length - 1]) {
console.log('------------------',selectNodes[selectNodes.length - 1].params)
let params = JSON.parse(selectNodes[selectNodes.length - 1].params) let params = JSON.parse(selectNodes[selectNodes.length - 1].params)
eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id); eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id);
} }
@ -73,6 +74,13 @@ export const useRightOperate = () => {
if (selectNodes && selectNodes[selectNodes.length - 1]) { if (selectNodes && selectNodes[selectNodes.length - 1]) {
let node = selectNodes[selectNodes.length - 1] let node = selectNodes[selectNodes.length - 1]
let params = JSON.parse(node.params) let params = JSON.parse(node.params)
if(!params) {
params = {
name: node.sourceName,
show: node.isShow,
id: node.id,
}
}
let entityObject = window.earth.entityMap.get(params.id) let entityObject = window.earth.entityMap.get(params.id)
entityObject.setCustomView() entityObject.setCustomView()
params.customView = entityObject.customView params.customView = entityObject.customView
@ -83,7 +91,7 @@ export const useRightOperate = () => {
"parentId": node.parentId, "parentId": node.parentId,
"treeIndex": node.treeIndex, "treeIndex": node.treeIndex,
"params": params, "params": params,
"isShow": node.isShow ? 1 : 0, "isShow": node.isShow ? 1 : 0 ? 1 : 0,
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
} }

View File

@ -435,8 +435,22 @@ export const useTree = () => {
for (let i = 0; i < zNodes.value.length; i++) { for (let i = 0; i < zNodes.value.length; i++) {
if (zNodes.value[i].params) { if (zNodes.value[i].params) {
let params = JSON.parse(zNodes.value[i].params) let params = JSON.parse(zNodes.value[i].params)
if (!params.id) {
params.id = zNodes.value[i].id
}
initMapData(zNodes.value[i].sourceType, params) initMapData(zNodes.value[i].sourceType, params)
} }
else {
//@ts-ignore
if (zNodes.value[i].detail) {
//@ts-ignore
let detail = JSON.parse(zNodes.value[i].detail)
if (!detail.id) {
detail.id = zNodes.value[i].id
}
initMapData(zNodes.value[i].sourceType, detail)
}
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
export const initMapData = async (type, data) => { export const initMapData = async (type, data) => {
let entityObject let entityObject
let options let options
console.log('data', type, data)
switch (type) { switch (type) {
case 'groundText': case 'groundText':
entityObject = new YJ.Obj.GroundText(window.earth, data) entityObject = new YJ.Obj.GroundText(window.earth, data)
@ -39,6 +40,18 @@ export const initMapData = async (type, data) => {
case 'model': case 'model':
entityObject = new YJ.Obj.ModelObject(window.earth, data) entityObject = new YJ.Obj.ModelObject(window.earth, data)
break break
case 'terrain':
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Terrain(window.earth, data)
break
case 'layer':
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Layer(window.earth, data)
break
case 'tileset':
data.host = 'http://192.168.110.25:8848'
entityObject = new YJ.Obj.Tileset(window.earth, data)
break
default: default:
return return
break break

View File

@ -18,6 +18,25 @@
accept=".jpeg,.png,.jpg,.mp4,.pdf" accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile" @input="uploadFile"
/> />
<!-- 多点视线分析 -->
<Visibility ref="visibility"></Visibility>
<CircleViewShed ref="CircleViewShed"></CircleViewShed>
<Submerge ref="Submerge"></Submerge>
<Profile ref="Profile"></Profile>
<ViewShed ref="ViewShed"></ViewShed>
<CutFill ref="CutFill"></CutFill>
<Contour ref="Contour"></Contour>
<RoutePlanning ref="RoutePlanning"></RoutePlanning>
<Graffiti ref="Graffiti"></Graffiti>
<!-- <FlyRoam ref="FlyRoam"></FlyRoam> -->
<CoorLocation ref="CoorLocation"></CoorLocation>
<ScreenShot ref="ScreenShot"></ScreenShot>
<TerrainExcavation ref="TerrainExcavation"></TerrainExcavation>
<ProjConvert ref="ProjConvert"></ProjConvert>
<ProjectionConvert ref="ProjectionConvert"></ProjectionConvert>
<GoodsSearchCircle ref="GoodsSearchCircle"></GoodsSearchCircle>
<GoodsSearchPolgon ref="GoodsSearchPolgon"></GoodsSearchPolgon>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -34,9 +53,28 @@ import attackArrow from '../components/propertyBox/attackArrow.vue'
import richText from '../components/propertyBox/richText.vue' import richText from '../components/propertyBox/richText.vue'
import groundText from '../components/propertyBox/groundText.vue' import groundText from '../components/propertyBox/groundText.vue'
import standText from '../components/propertyBox/standText.vue' import standText from '../components/propertyBox/standText.vue'
import circleObject from '../components/propertyBox/circleObject.vue'
import addDirectory from '@/components/dialog/directory.vue' import addDirectory from '@/components/dialog/directory.vue'
import firstMenu from '@/views/components/leftSide/leftSideFirst.vue' import firstMenu from '@/views/components/leftSide/leftSideFirst.vue'
import bottomMenu from '@/views/components/bottomSide/bottomSide.vue' import bottomMenu from '@/views/components/bottomSide/bottomSide.vue'
import Visibility from '../components/propertyBox/Visibility.vue'
import CircleViewShed from '../components/propertyBox/CircleViewShed.vue'
import Submerge from '../components/propertyBox/Submerge.vue'
import Profile from '../components/propertyBox/Profile.vue'
import ViewShed from '../components/propertyBox/ViewShed.vue'
import CutFill from '../components/propertyBox/CutFill.vue'
import Contour from '../components/propertyBox/Contour.vue'
import RoutePlanning from '../components/propertyBox/RoutePlanning.vue'
import Graffiti from '../components/propertyBox/Graffiti.vue'
import FlyRoam from '../components/propertyBox/FlyRoam.vue'
import CoorLocation from '../components/propertyBox/CoorLocation.vue'
import ScreenShot from '../components/propertyBox/ScreenShot.vue'
import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue'
import ProjConvert from '../components/propertyBox/ProjConvert.vue'
import ProjectionConvert from '../components/propertyBox/ProjectionConvert.vue'
import GoodsSearchCircle from '../components/propertyBox/GoodsSearchCircle.vue'
import GoodsSearchPolgon from '../components/propertyBox/GoodsSearchPolgon.vue'
import { GisApi } from '@/api/gisApi' import { GisApi } from '@/api/gisApi'
const firstMenuRef = ref(null) const firstMenuRef = ref(null)
@ -56,7 +94,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
case 'groundText': case 'groundText':
currentComponent.value = groundText currentComponent.value = groundText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open(id)
break break
case 'addStandText': case 'addStandText':
currentComponent.value = addStandText currentComponent.value = addStandText
@ -66,7 +104,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
case 'standText': case 'standText':
currentComponent.value = standText currentComponent.value = standText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open(id)
break break
case 'point': case 'point':
currentComponent.value = billboardObject currentComponent.value = billboardObject
@ -90,6 +128,9 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break break
case 'circle': case 'circle':
currentComponent.value = circleObject
await nextTick()
dynamicComponentRef.value?.open(id, 'circle')
break break
case 'rectangle': case 'rectangle':
currentComponent.value = polygonObject currentComponent.value = polygonObject
@ -97,7 +138,7 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
dynamicComponentRef.value?.open(id, 'rectangle') dynamicComponentRef.value?.open(id, 'rectangle')
break break
case 'rendezvous': case 'rendezvous':
currentComponent.value = rendezvous currentComponent.value = polygonObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id, 'rendezvous') dynamicComponentRef.value?.open(id, 'rendezvous')
break break