点标注设置新增时的默认样式;增加后端数据存储文件路径设置

This commit is contained in:
zh
2025-11-19 10:36:20 +08:00
parent 44b3fbef50
commit ff2bfca6a9
29 changed files with 996 additions and 675 deletions

View File

@ -1,6 +1,10 @@
server: server:
host: 127.0.0.1 host: 127.0.0.1
port: 8848 port: 8848
path: C:\Users\MSI\AppData\Roaming\dzsp_shijingjun_offline_Y_save
poi:
global:
enabled: false
sdk: sdk:
port: 8888 port: 8888
spring: spring:

View File

@ -1 +1 @@
41b/ujShRZRf9Aa433FD3uyIZuxWSSqXWXlc2dyQfJ75ED0HNbadcdsPF5CaMuJ624E+iLBfS14muki3Kp1qv3N0KPVdc0TjJDyrO+AVfwFghRHbXEWYEGb3GpmVU0MwclqNNggKfnTvj0gDIpFBNl/nxMZKwYXbYk8nqd3yUDfwLryTr1ScTPGegLiv1C+r1SDxtenx4d2fxqS6FkGbV5TA9+UoajQ1PHwDUdI7SfpxjvK4tQscOcu0R0wLgUa3LypkZtybW+yeNEhnp/jeYw== 41b/ujShRZRf9Aa433FD3uyIZuxWSSqXWXlc2dyQfJ75ED0HNbadcdsPF5CaMuJ624E+iLBfS14muki3Kp1qv3N0KPVdc0TjJDyrO+AVfwE2pkhuoGoZ8sNGSUSrom2NhRIwJNl4SNhqGkxKvDJhRhWfxw6LHS3T/4NDVmw/KlXwLryTr1ScTPGegLiv1C+r0BN58Qcbdy/IN4J0/xuadZTA9+UoajQ1PHwDUdI7SfpTyz/mXYghVpbQcW8OYTHqLypkZtybW+yeNEhnp/jeYw==

View File

@ -13,6 +13,8 @@ const http = require("http");
const yaml = require("js-yaml"); const yaml = require("js-yaml");
let Store = require('electron-store') let Store = require('electron-store')
Store.initRenderer(); Store.initRenderer();
const store = new Store()
process.on('unhandledRejection', (reason) => { process.on('unhandledRejection', (reason) => {
console.error('主进程异步异常:', reason); console.error('主进程异步异常:', reason);
@ -128,6 +130,10 @@ function createWindow(): void {
}) })
let ymlBatPath = process.env.NODE_ENV === 'development' ? path.resolve(app.getAppPath(), 'resources', 'java', 'app', 'application.yml') : path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'app', 'application.yml') let ymlBatPath = process.env.NODE_ENV === 'development' ? path.resolve(app.getAppPath(), 'resources', 'java', 'app', 'application.yml') : path.join(process.resourcesPath, 'app.asar.unpacked', 'resources', 'java', 'app', 'application.yml')
ymlBatPath = process.platform === 'win32' ? ymlBatPath.replace(/^(\w:)/, '/$1') : ymlBatPath ymlBatPath = process.platform === 'win32' ? ymlBatPath.replace(/^(\w:)/, '/$1') : ymlBatPath
let ymlPath = ymlBatPath.substring(1, 200)
const ymlContent = yaml.load(fs.readFileSync(ymlPath, 'utf8'));
ymlContent.server.path = path.dirname(store.path)
fs.writeFileSync(ymlPath, yaml.dump(ymlContent));
ipcMain.on("getIniConfig", (event, option) => { ipcMain.on("getIniConfig", (event, option) => {
let ymlPath = ymlBatPath.substring(1, 200) let ymlPath = ymlBatPath.substring(1, 200)
console.log("iniPath", ymlPath); console.log("iniPath", ymlPath);
@ -415,8 +421,6 @@ function createWindow(): void {
"1300", "1300",
"-y", "-y",
"730", "730",
"-rtsp_transport",
"tcp",
obj.url, obj.url,
], ],
{ {
@ -428,6 +432,9 @@ function createWindow(): void {
console.log("out"); console.log("out");
console.log(err); console.log(err);
e.sender.send("openFFPlayOut", err); e.sender.send("openFFPlayOut", err);
if (obj.id) {
e.sender.send("openFFPlayOut_" + obj.id, err, obj.id);
}
}); });
/* .on("stdout", function(err, m) { /* .on("stdout", function(err, m) {
@ -502,7 +509,7 @@ function windowAllClosed() {
setTimeout(() => { setTimeout(() => {
if (isQuitting) { if (isQuitting) {
console.log('清理脚本执行超时,强制退出'); console.log('清理脚本执行超时,强制退出');
cleanupProcess.kill(); // 终止卡住的脚本 // cleanupProcess.kill(); // 终止卡住的脚本
forceQuit(); forceQuit();
} }
}, 3000); // 3秒超时 }, 3000); // 3秒超时

View File

@ -26,7 +26,6 @@ declare module 'vue' {
ElOption: typeof import('element-plus/es')['ElOption'] ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination'] ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm'] ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRow: typeof import('element-plus/es')['ElRow'] ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect'] ElSelect: typeof import('element-plus/es')['ElSelect']
ElSlider: typeof import('element-plus/es')['ElSlider'] ElSlider: typeof import('element-plus/es')['ElSlider']

File diff suppressed because one or more lines are too long

View File

@ -297,11 +297,6 @@
flex-wrap: wrap; flex-wrap: wrap;
} }
.YJ-custom-base-dialog>.content .row .input-select-unit-box,
.YJ-custom-base-dialog>.content .row .input-select-fit-unit-box {
flex: 0 0 270px;
}
.YJ-custom-base-dialog>.content .row:last-child { .YJ-custom-base-dialog>.content .row:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
@ -424,7 +419,8 @@
} }
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add_btn, .YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add_btn,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add_btn { .YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add_btn,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .rtmp_add_btn {
display: inline-block; display: inline-block;
width: 20px; width: 20px;
height: 20px; height: 20px;
@ -436,12 +432,14 @@
} }
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add, .YJ-custom-base-dialog>.content .attribute .attribute-content-link .link_add,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add { .YJ-custom-base-dialog>.content .attribute .attribute-content-vr .vr_add,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .rtmp_add {
padding-right: 30px; padding-right: 30px;
} }
.YJ-custom-base-dialog>.content .attribute .attribute-content-link .tr .td:last-child button:first-child, .YJ-custom-base-dialog>.content .attribute .attribute-content-link .tr .td:last-child button:first-child,
.YJ-custom-base-dialog>.content .attribute .attribute-content-vr .tr .td:last-child button:first-child { .YJ-custom-base-dialog>.content .attribute .attribute-content-vr .tr .td:last-child button:first-child,
.YJ-custom-base-dialog>.content .attribute .attribute-content-rtmp .tr .td:last-child button:first-child {
margin-right: 5px; margin-right: 5px;
} }
@ -531,7 +529,8 @@
} }
.YJ-custom-base-dialog>.content .attribute-content-link .table .table-body, .YJ-custom-base-dialog>.content .attribute-content-link .table .table-body,
.YJ-custom-base-dialog>.content .attribute-content-vr .table .table-body { .YJ-custom-base-dialog>.content .attribute-content-vr .table .table-body,
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .table-body {
max-height: 172px; max-height: 172px;
} }
@ -2514,7 +2513,9 @@
.YJ-custom-base-dialog.polygon>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog.polygon>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.polygon>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.polygon>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.polygon>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.polygon>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.polygon>.content .attribute-content-vr .table .tr .td:nth-child(3) { .YJ-custom-base-dialog.polygon>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.polygon>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.polygon>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 165px; flex: 0 0 165px;
width: 165px; width: 165px;
justify-content: center; justify-content: center;
@ -2596,7 +2597,9 @@
.YJ-custom-base-dialog.assemble>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog.assemble>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.assemble>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.assemble>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.assemble>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.assemble>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.assemble>.content .attribute-content-vr .table .tr .td:nth-child(3) { .YJ-custom-base-dialog.assemble>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.assemble>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.assemble>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 165px; flex: 0 0 165px;
width: 165px; width: 165px;
justify-content: center; justify-content: center;
@ -2643,14 +2646,20 @@
.YJ-custom-base-dialog.circle>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.circle>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.circle>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.circle>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.circle>.content .attribute-content-vr .table .tr .td:nth-child(3), .YJ-custom-base-dialog.circle>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.circle>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.circle>.content .attribute-content-rtmp .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog.attackArrow>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.attackArrow>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.attackArrow>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-vr .table .tr .td:nth-child(3), .YJ-custom-base-dialog.attackArrow>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.attackArrow>.content .attribute-content-rtmp .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog.pincerArrow>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.pincerArrow>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.pincerArrow>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-vr .table .tr .td:nth-child(3) { .YJ-custom-base-dialog.pincerArrow>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.pincerArrow>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 165px; flex: 0 0 165px;
width: 165px; width: 165px;
justify-content: center; justify-content: center;
@ -2946,8 +2955,9 @@
.YJ-custom-base-dialog.polyline>.content input.input-text { .YJ-custom-base-dialog.polyline>.content input.input-text {
background-color: rgba(0, 0, 0, 0.5) !important; background-color: rgba(0, 0, 0, 0.5) !important;
border-radius: unset !important; border-radius: unset !important;
border-top: 1px solid rgba(var(--color-base1), 0.5) !important; border: none;
border-bottom: 1px solid rgba(var(--color-base1), 0.5) !important; border-top: 1px solid rgba(var(--color-base1), 0.7) !important;
border-bottom: 1px solid rgba(var(--color-base1), 0.7) !important;
} }
.YJ-custom-base-dialog.polyline>.content>div .input-select-line-type-box .cy_datalist input { .YJ-custom-base-dialog.polyline>.content>div .input-select-line-type-box .cy_datalist input {
@ -3133,7 +3143,9 @@
.YJ-custom-base-dialog.model>.content .attribute-content-link .table .tr .th:nth-child(2), .YJ-custom-base-dialog.model>.content .attribute-content-link .table .tr .th:nth-child(2),
.YJ-custom-base-dialog.model>.content .attribute-content-link .table .tr .td:nth-child(2), .YJ-custom-base-dialog.model>.content .attribute-content-link .table .tr .td:nth-child(2),
.YJ-custom-base-dialog.model>.content .attribute-content-vr .table .tr .th:nth-child(2), .YJ-custom-base-dialog.model>.content .attribute-content-vr .table .tr .th:nth-child(2),
.YJ-custom-base-dialog.model>.content .attribute-content-vr .table .tr .td:nth-child(2) { .YJ-custom-base-dialog.model>.content .attribute-content-vr .table .tr .td:nth-child(2),
.YJ-custom-base-dialog.model>.content .attribute-content-rtmp .table .tr .th:nth-child(2),
.YJ-custom-base-dialog.model>.content .attribute-content-rtmp .table .tr .td:nth-child(2) {
flex: 0 0 210px; flex: 0 0 210px;
width: 210px; width: 210px;
justify-content: center; justify-content: center;

View File

@ -259,6 +259,7 @@ export default {
ISC摄像头: 'ISC摄像头', ISC摄像头: 'ISC摄像头',
: '传感器', : '传感器',
: '全景图', : '全景图',
rtmp: 'rtmp',
: '物资', : '物资',
: '编辑内容', : '编辑内容',
: '打开文本编辑器', : '打开文本编辑器',

View File

@ -258,6 +258,7 @@ export default {
ISC摄像头: 'ISC Camera', ISC摄像头: 'ISC Camera',
: 'Sensor', : 'Sensor',
: 'Panorama photo', : 'Panorama photo',
rtmp: 'rtmp',
: 'Materials', : 'Materials',
: 'Edit content', : 'Edit content',
: 'Open the editor', : 'Open the editor',

View File

@ -257,6 +257,7 @@ export default {
ISC摄像头: 'ISC攝像頭', ISC摄像头: 'ISC攝像頭',
: '傳感器', : '傳感器',
: '全景圖', : '全景圖',
rtmp: 'rtmp',
: '物資', : '物資',
: '編輯內容', : '編輯內容',
: '打開文本編輯器', : '打開文本編輯器',

View File

@ -415,11 +415,11 @@ img {
.ztree li span.button.chk { .ztree li span.button.chk {
background: none; background: none;
} }
.ztree li span.button.roots_open, .ztree li span.button.bottom_open, .ztree li span.button.center_open { .ztree li span.button.root_open, .ztree li span.button.roots_open, .ztree li span.button.bottom_open, .ztree li span.button.center_open {
background: url(../images/tree/roots-open.png) 0 0 no-repeat; background: url(../images/tree/roots-open.png) 0 0 no-repeat;
background-position: center !important; background-position: center !important;
} }
.ztree li span.button.roots_close, .ztree li span.button.bottom_close, .ztree li span.button.center_close{ .ztree li span.button.root_close, .ztree li span.button.roots_close, .ztree li span.button.bottom_close, .ztree li span.button.center_close{
background: url(../images/tree/roots-close.png) 0 0 no-repeat; background: url(../images/tree/roots-close.png) 0 0 no-repeat;
background-position: center !important; background-position: center !important;
} }
@ -605,6 +605,22 @@ img {
bottom: 126px !important; bottom: 126px !important;
right: 16px !important; right: 16px !important;
} }
.YJ-custom-base-dialog>.content .row .input-select-unit-box {
.el-select {
.el-select__wrapper {
border: 1px solid rgba(var(--color-base1), 0.5);
}
&:nth-of-type(1) .el-select__wrapper {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&:nth-of-type(2) .el-select__wrapper {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
}
} }
.custom-slider-tooltip { .custom-slider-tooltip {

View File

@ -19,6 +19,9 @@ export const addMapSource = async ({type, id, sourceName = '未命名对象', op
} }
} }
delete options.host delete options.host
if(options.attribute && options.attribute.rtmp) {
delete options.attribute.rtmp
}
switch (type) { switch (type) {
case 'rendezvous': case 'rendezvous':
case 'attackArrow': case 'attackArrow':

View File

@ -11,7 +11,7 @@
</div> </div>
<div class="boxBody"> <div class="boxBody">
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px" <el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px"
@keyup.enter.native="submitForm(ruleForm)"> @keyup.enter.native="submitForm(ruleForm)" @submit.native.prevent>
<el-form-item label="名称:" prop="sourceName"> <el-form-item label="名称:" prop="sourceName">
<!-- @input="removeSpaces" --> <!-- @input="removeSpaces" -->
<el-input v-model.trim="form.sourceName" placeholder="图层文件夹"></el-input> <el-input v-model.trim="form.sourceName" placeholder="图层文件夹"></el-input>

View File

@ -11,7 +11,7 @@
</div> </div>
<div class="boxBody"> <div class="boxBody">
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px" <el-form :model="form" :rules="rules" ref="ruleForm" label-width="80px"
@keyup.enter.native="submitForm(ruleForm)"> @keyup.enter.native="submitForm(ruleForm)" @submit.native.prevent>
<el-form-item label="名称:" prop="sourceName"> <el-form-item label="名称:" prop="sourceName">
<!-- @input="removeSpaces" --> <!-- @input="removeSpaces" -->
<el-input v-model.trim="form.sourceName" placeholder="节点名称"></el-input> <el-input v-model.trim="form.sourceName" placeholder="节点名称"></el-input>
@ -49,9 +49,11 @@ const removeSpaces = (value: string) => {
} }
const close = () => { const close = () => {
$changeComponentPop('.editdirectoryBox', false) $changeComponentPop('.editdirectoryBox', false)
setTimeout(() => {
sourceId.value = '' sourceId.value = ''
form.sourceName = '' form.sourceName = ''
ruleForm.value?.resetFields() ruleForm.value?.resetFields()
}, 200);
} }
const submitForm = async (formEl: FormInstance | undefined) => { const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
@ -69,6 +71,7 @@ const add = throttle(async () => {
sourceName: form.sourceName sourceName: form.sourceName
}) })
cusUpdateNode({ id: sourceId.value, sourceName: form.sourceName, params: undefined }) cusUpdateNode({ id: sourceId.value, sourceName: form.sourceName, params: undefined })
close()
// console.log(res) // console.log(res)
}, 3000) }, 3000)
// //上传或修改树的层级 // //上传或修改树的层级

View File

@ -134,7 +134,7 @@ import NewPlan from "./newPlan.vue"
const date = ref({ const date = ref({
ymd: '', ymd: '',
hms: '', hms: '',
week: 0 week: ""
}) })
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
const {ipcRenderer} = require('electron') const {ipcRenderer} = require('electron')

View File

@ -194,6 +194,34 @@ const bottomMenuList = ref([
} }
let id = new YJ.Tools().randomString() let id = new YJ.Tools().randomString()
let name = t(`default.point`) let name = t(`default.point`)
let defaultStyle = (JSON.parse(localStorage.getItem('defaultStyle') || '{}').point) || {}
if(!defaultStyle) {
defaultStyle = {}
}
if(!defaultStyle.billboard) {
defaultStyle.billboard = {}
}
if(!defaultStyle.label) {
defaultStyle.label = {}
}
if(defaultStyle.billboard.image) {
try {
let urlObject = new URL(defaultStyle.billboardimage)
let pathname = urlObject.pathname
let folderName = pathname.split('/')[1]
if(folderName === 'iconLibrary') {
let ip = localStorage.getItem('ip') || ''
let ipObject = new URL(ip)
urlObject.port = ipObject.port
defaultStyle.billboard.image = urlObject.href
}
else {
urlObject.port = availablePort.value+''
defaultStyle.billboard.image = urlObject.href
}
} catch (error) {
}
}
await addMapSource({ await addMapSource({
type: 'point', type: 'point',
id: id, id: id,
@ -203,13 +231,19 @@ const bottomMenuList = ref([
name: name, name: name,
position: position, position: position,
billboard: { billboard: {
show: true, show: defaultStyle.billboard.show || true,
image: image:
YJ.Global.getBillboardDefaultUrl() || defaultStyle.billboard.image || "http://localhost:" +
"http://localhost:" +
availablePort.value + availablePort.value +
"/" + "/" +
"GEMarker1/A-ablu-blank.png", "GEMarker1/A-ablu-blank.png",
scale: defaultStyle.billboard.scale || 3,
},
label: {
show: defaultStyle.show || true,
color: defaultStyle.label.color,
fontFamily: defaultStyle.label.fontFamily,
fontSize: defaultStyle.label.fontSize,
} }
} }
}) })
@ -232,6 +266,7 @@ const bottomMenuList = ref([
} }
let id = new YJ.Tools().randomString() let id = new YJ.Tools().randomString()
let name = t(`default.line`) let name = t(`default.line`)
let defaultStyle = (JSON.parse(localStorage.getItem('defaultStyle') || '{}').line) || {}
await addMapSource({ await addMapSource({
type: 'line', type: 'line',
id: id, id: id,
@ -239,7 +274,18 @@ const bottomMenuList = ref([
opt: { opt: {
id: id, id: id,
name: name, name: name,
positions: positions positions: positions,
color: defaultStyle.color,
width: defaultStyle.width,
type: defaultStyle.type,
noseToTail: defaultStyle.noseToTail,
smooth: defaultStyle.smooth,
extend: defaultStyle.extend,
extendWidth: defaultStyle.extendWidth,
extendColor: defaultStyle.extendColor,
rotate: defaultStyle.rotate,
speed: defaultStyle.speed,
space: defaultStyle.space,
} }
}) })
}) })
@ -259,6 +305,7 @@ const bottomMenuList = ref([
} }
let id = new YJ.Tools().randomString() let id = new YJ.Tools().randomString()
let name = t(`default.curve`) let name = t(`default.curve`)
let defaultStyle = (JSON.parse(localStorage.getItem('defaultStyle') || '{}').curve) || {}
await addMapSource({ await addMapSource({
type: 'curve', type: 'curve',
id: id, id: id,
@ -266,7 +313,17 @@ const bottomMenuList = ref([
opt: { opt: {
id: id, id: id,
name: name, name: name,
positions: positions positions: positions,
color: defaultStyle.color,
width: defaultStyle.width,
type: defaultStyle.type,
noseToTail: defaultStyle.noseToTail,
extend: defaultStyle.extend,
extendWidth: defaultStyle.extendWidth,
extendColor: defaultStyle.extendColor,
rotate: defaultStyle.rotate,
speed: defaultStyle.speed,
space: defaultStyle.space,
} }
}) })
}) })

View File

@ -20,7 +20,7 @@
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col">
<span class="label">等高距</span> <span class="label">等高距</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input
@ -35,8 +35,8 @@
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col input-select-unit-box" style="flex: 0 0 60px"></div> <div class="col" style="flex: 0 0 60px"></div>
<div class="col input-select-unit-box" style="flex: 0 0 157px"> <div class="col" style="flex: 0 0 157px">
<span class="label">选中线颜色</span> <span class="label">选中线颜色</span>
<div class="active-color"></div> <div class="active-color"></div>
</div> </div>
@ -49,11 +49,11 @@
<span class="label">计曲线</span> <span class="label">计曲线</span>
<input class="btn-switch index-contour-switch" type="checkbox" /> <input class="btn-switch index-contour-switch" type="checkbox" />
</div> </div>
<div class="col input-select-unit-box" style="flex: 0 0 120px"> <div class="col" style="flex: 0 0 120px">
<span class="label">计曲线颜色</span> <span class="label">计曲线颜色</span>
<div class="index-contour-color"></div> <div class="index-contour-color"></div>
</div> </div>
<div class="col input-select-unit-box"> <div class="col">
<span class="label">计曲线宽度</span> <span class="label">计曲线宽度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input
@ -74,11 +74,11 @@
<span class="label">首曲线</span> <span class="label">首曲线</span>
<input class="btn-switch intermediate-contour-switch" type="checkbox" /> <input class="btn-switch intermediate-contour-switch" type="checkbox" />
</div> </div>
<div class="col input-select-unit-box" style="flex: 0 0 120px"> <div class="col" style="flex: 0 0 120px">
<span class="label">首曲线颜色</span> <span class="label">首曲线颜色</span>
<div class="intermediate-contour-color"></div> <div class="intermediate-contour-color"></div>
</div> </div>
<div class="col input-select-unit-box"> <div class="col">
<span class="label">首曲线宽度</span> <span class="label">首曲线宽度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input
@ -99,11 +99,11 @@
<span class="label">间曲线</span> <span class="label">间曲线</span>
<input class="btn-switch halfInterval-contour-switch" type="checkbox" /> <input class="btn-switch halfInterval-contour-switch" type="checkbox" />
</div> </div>
<div class="col input-select-unit-box" style="flex: 0 0 120px"> <div class="col" style="flex: 0 0 120px">
<span class="label">间曲线颜色</span> <span class="label">间曲线颜色</span>
<div class="halfInterval-contour-color"></div> <div class="halfInterval-contour-color"></div>
</div> </div>
<div class="col input-select-unit-box"> <div class="col">
<span class="label">间曲线宽度</span> <span class="label">间曲线宽度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input
@ -123,11 +123,11 @@
<span class="label">助曲线</span> <span class="label">助曲线</span>
<input class="btn-switch supplementary-contour-switch" type="checkbox" /> <input class="btn-switch supplementary-contour-switch" type="checkbox" />
</div> </div>
<div class="col input-select-unit-box" style="flex: 0 0 120px"> <div class="col" style="flex: 0 0 120px">
<span class="label">助曲线颜色</span> <span class="label">助曲线颜色</span>
<div class="supplementary-contour-color"></div> <div class="supplementary-contour-color"></div>
</div> </div>
<div class="col input-select-unit-box"> <div class="col">
<span class="label">助曲线宽度</span> <span class="label">助曲线宽度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input

View File

@ -45,11 +45,11 @@
<textarea class="input link-edit" type="text" v-model="linkEditActive.url"></textarea> <textarea class="input link-edit" type="text" v-model="linkEditActive.url"></textarea>
</div> </div>
<div class="td" v-else>{{ item.url }}</div> <div class="td" v-else>{{ item.url }}</div>
<div class="td" v-if="linkEditActive.index === index"> <div class="td operation" v-if="linkEditActive.index === index">
<button style="width: 76px;flex: 0 0 76px" @click="linkConfirmEdit(index)">{{ t('general.确认') }}</button> <button style="width: 76px;flex: 0 0 76px" @click="linkConfirmEdit(index)">{{ t('general.确认') }}</button>
<button style="width: 76px;flex: 0 0 76px" @click="linkCancelEdit">{{ t('general.取消') }}</button> <button style="width: 76px;flex: 0 0 76px" @click="linkCancelEdit">{{ t('general.取消') }}</button>
</div> </div>
<div class="td" v-else> <div class="td operation" v-else>
<button style="width: 76px;flex: 0 0 76px" @click="linkEdit(index, item)">{{ t('general.编辑') }}</button> <button style="width: 76px;flex: 0 0 76px" @click="linkEdit(index, item)">{{ t('general.编辑') }}</button>
<button style="width: 76px;flex: 0 0 76px" @click="linkDelete(index)">{{ t('general.删除') }}</button> <button style="width: 76px;flex: 0 0 76px" @click="linkDelete(index)">{{ t('general.删除') }}</button>
</div> </div>
@ -172,13 +172,57 @@
<textarea class="input link-edit" type="text" v-model="vrEditActive.url"></textarea> <textarea class="input link-edit" type="text" v-model="vrEditActive.url"></textarea>
</div> </div>
<div class="td" v-else>{{ item.url }}</div> <div class="td" v-else>{{ item.url }}</div>
<div class="td" v-if="vrEditActive.index === index"> <div class="td operation" v-if="vrEditActive.index === index">
<button style="width: 76px;flex: 0 0 76px" @click="vrConfirmEdit(index)">{{ t('general.确认') }}</button> <button @click="vrConfirmEdit(index)">{{ t('general.确认') }}</button>
<button style="width: 76px;flex: 0 0 76px" @click="vrCancelEdit">{{ t('general.取消') }}</button> <button @click="vrCancelEdit">{{ t('general.取消') }}</button>
</div> </div>
<div class="td" v-else> <div class="td operation" v-else>
<button style="width: 76px;flex: 0 0 76px" @click="vrEdit(index, item)">{{ t('general.编辑') }}</button> <button @click="vrEdit(index, item)">{{ t('general.编辑') }}</button>
<button style="width: 76px;flex: 0 0 76px" @click="vrDelete(index)">{{ t('general.删除') }}</button> <button @click="vrDelete(index)">{{ t('general.删除') }}</button>
</div>
</div>
</div>
<div class="table-empty" v-else>
<div class="empty-img"></div>
<p>{{ t('general.暂无数据') }}</p>
</div>
</div>
</div>
<div class="row attribute-content attribute-content-rtmp" v-show="attributeType === 'rtmp'">
<div class="col">
<span class="label">{{ t('general.添加链接') }}</span>
<div style="flex: 1; position: relative">
<input class="input rtmp_add" type="text" v-model="addRtmpInput" />
<i class="rtmp_add_btn" @click="_addRtmp"></i>
</div>
</div>
</div>
<div class="attribute-content attribute-content-rtmp" v-show="attributeType === 'rtmp'">
<div class="table">
<div class="table-head">
<div class="tr">
<div class="th">{{ t('general.名称') }}</div>
<div class="th">{{ t('general.链接') }}</div>
<div class="th">{{ t('general.操作') }}</div>
</div>
</div>
<div class="table-body" v-if="attribute.rtmp && attribute.rtmp.content && attribute.rtmp.content.length > 0">
<div class="tr" v-for="(item, index) in attribute.rtmp.content">
<div class="td" v-if="rtmpEditActive.index === index">
<input class="input" type="text" v-model="rtmpEditActive.name" />
</div>
<div class="td" v-else>{{ item.name }}</div>
<div class="td" v-if="rtmpEditActive.index === index">
<textarea class="input link-edit" type="text" v-model="rtmpEditActive.url"></textarea>
</div>
<div class="td" v-else>{{ item.url }}</div>
<div class="td operation" v-if="rtmpEditActive.index === index">
<button @click="rtmpConfirmEdit(index)">{{ t('general.确认') }}</button>
<button @click="rtmpCancelEdit">{{ t('general.取消') }}</button>
</div>
<div class="td operation" v-else>
<button @click="rtmpEdit(index, item)">{{ t('general.编辑') }}</button>
<button @click="rtmpDelete(index)">{{ t('general.删除') }}</button>
</div> </div>
</div> </div>
</div> </div>
@ -386,6 +430,11 @@ if (props.entityOptions.type === 'BillboardObject') {
// value: '传感器', // value: '传感器',
// key: 'sensor' // key: 'sensor'
// }, // },
// {
// name: 'rtmp',
// value: 'rtmp',
// key: 'rtmp'
// },
{ {
name: '全景图', name: '全景图',
value: '全景图', value: '全景图',
@ -404,8 +453,10 @@ if (props.entityOptions.type === 'BillboardObject') {
const addlinkInput = ref('') const addlinkInput = ref('')
const addvrInput = ref('') const addvrInput = ref('')
const addRtmpInput = ref('')
const linkEditActive: any = ref({}) const linkEditActive: any = ref({})
const vrEditActive: any = ref({}) const vrEditActive: any = ref({})
const rtmpEditActive: any = ref({})
const openRichTextEditor = () => { const openRichTextEditor = () => {
eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val: any) => { eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val: any) => {
@ -571,6 +622,38 @@ const vrCancelEdit = () => {
vrEditActive.value = {} vrEditActive.value = {}
} }
const _addRtmp = () => {
if (addRtmpInput.value) {
let link = {
name: t('general.rtmp'),
url: addRtmpInput.value,
id: Date.now()
}
attribute.value.rtmp.content.push(link)
addRtmpInput.value = ''
}
}
const rtmpEdit = (index: any, item: { name: any; url: any; }) => {
let active = {
index: index,
name: item.name,
url: item.url,
id: item.id,
}
rtmpEditActive.value = active
}
const rtmpDelete = (index: any) => {
attribute.value.rtmp.content.splice(index, 1)
}
const rtmpConfirmEdit = (index: string | number) => {
attribute.value.rtmp.content[index] = rtmpEditActive.value
rtmpEditActive.value = {}
}
const rtmpCancelEdit = () => {
rtmpEditActive.value = {}
}
const attributeChange = () => { } const attributeChange = () => { }
const changeAttributeGoods = (item) => { const changeAttributeGoods = (item) => {
@ -633,7 +716,9 @@ const changeAttributeCamera = (e) => {
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(1), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(1), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(1), .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(1) { .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(1),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(1) {
width: 164px; width: 164px;
flex: 0 0 164px; flex: 0 0 164px;
} }
@ -641,7 +726,9 @@ const changeAttributeCamera = (e) => {
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(2), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(2), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(2), .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(2) { .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(2),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(2) {
width: 226px; width: 226px;
flex: 0 0 226px; flex: 0 0 226px;
} }
@ -649,7 +736,9 @@ const changeAttributeCamera = (e) => {
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(3) { .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 150px; flex: 0 0 150px;
width: 150px; width: 150px;
justify-content: center; justify-content: center;
@ -657,14 +746,17 @@ const changeAttributeCamera = (e) => {
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-link .table .tr .th:nth-child(3), .YJ-custom-base-dialog.dialog-en>.content .attribute-content-link .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-link .table .tr .td:nth-child(3), .YJ-custom-base-dialog.dialog-en>.content .attribute-content-link .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-vr .table .tr .th:nth-child(3), .YJ-custom-base-dialog.dialog-en>.content .attribute-content-vr .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-vr .table .tr .td:nth-child(3) { .YJ-custom-base-dialog.dialog-en>.content .attribute-content-vr .table .tr .td:nth-child(3),
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-rtmp .table .tr .th:nth-child(3),
.YJ-custom-base-dialog.dialog-en>.content .attribute-content-rtmp .table .tr .td:nth-child(3) {
flex: 0 0 190px; flex: 0 0 190px;
width: 190px; width: 190px;
justify-content: center; justify-content: center;
} }
.YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td .input-group .input, .YJ-custom-base-dialog>.content .attribute-content-link .table .tr .td .input-group .input,
.YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td .input-group .input { .YJ-custom-base-dialog>.content .attribute-content-vr .table .tr .td .input-group .input,
.YJ-custom-base-dialog>.content .attribute-content-rtmp .table .tr .td .input-group .input {
border-radius: 5px 0 0 5px; border-radius: 5px 0 0 5px;
} }

View File

@ -86,7 +86,7 @@
</div> </div>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<!-- <setStyle type="点" :sourceType="sourceType" :entityOptions="entityOptions"></setStyle> --> <setStyle type="点" :sourceType="sourceType" :entityOptions="entityOptions"></setStyle>
<div class="row" style="padding-left: 12px;"> <div class="row" style="padding-left: 12px;">
<div class="col"> <div class="col">
<span class="label" style="flex: none">{{ t('dialog.point.icon.show') }}</span> <span class="label" style="flex: none">{{ t('dialog.point.icon.show') }}</span>
@ -339,6 +339,7 @@
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
<span class="custom-divider"></span>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex"> <div style="position: absolute; left: 24px; display: flex">
@ -467,47 +468,48 @@ const open = async (id, type) => {
entityOptions.value.labelColor = 'rgba(255,255,255,1)' entityOptions.value.labelColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调 } //点击清空按钮事件回调
}) })
let iconTextBold = document.getElementsByClassName('bold')[0]
let iconTextItalic = document.getElementsByClassName('italic')[0] // let iconTextBold = document.getElementsByClassName('bold')[0]
let iconTextLineBottom = document.getElementsByClassName('line-bottom')[0] // let iconTextItalic = document.getElementsByClassName('italic')[0]
let iconTextLineThrough = document.getElementsByClassName('line-through')[0] // let iconTextLineBottom = document.getElementsByClassName('line-bottom')[0]
let tip: any = document.getElementsByClassName('customized-tip')[0] // let iconTextLineThrough = document.getElementsByClassName('line-through')[0]
iconTextBold.addEventListener('mouseleave', (event:any) => { // let tip: any = document.getElementsByClassName('customized-tip')[0]
tip.style.display = 'none' // iconTextBold.addEventListener('mouseleave', (event:any) => {
}) // tip.style.display = 'none'
iconTextBold.addEventListener('mousemove', (event:any) => { // })
tip.innerHTML = t('general.text.bold') // iconTextBold.addEventListener('mousemove', (event:any) => {
tip.style.left = (event.layerX + 8) + 'px' // tip.innerHTML = t('general.text.bold')
tip.style.top = (event.layerY + 18) + 'px' // tip.style.left = (event.layerX + 8) + 'px'
tip.style.display = 'block' // tip.style.top = (event.layerY + 18) + 'px'
}) // tip.style.display = 'block'
iconTextItalic.addEventListener('mouseleave', (event:any) => { // })
tip.style.display = 'none' // iconTextItalic.addEventListener('mouseleave', (event:any) => {
}) // tip.style.display = 'none'
iconTextItalic.addEventListener('mousemove', (event:any) => { // })
tip.innerHTML = t('general.text.italic') // iconTextItalic.addEventListener('mousemove', (event:any) => {
tip.style.left = (event.layerX + 8) + 'px' // tip.innerHTML = t('general.text.italic')
tip.style.top = (event.layerY + 18) + 'px' // tip.style.left = (event.layerX + 8) + 'px'
tip.style.display = 'block' // tip.style.top = (event.layerY + 18) + 'px'
}) // tip.style.display = 'block'
iconTextLineBottom.addEventListener('mouseleave', (event:any) => { // })
tip.style.display = 'none' // iconTextLineBottom.addEventListener('mouseleave', (event:any) => {
}) // tip.style.display = 'none'
iconTextLineBottom.addEventListener('mousemove', (event:any) => { // })
tip.innerHTML = t('general.text.underline') // iconTextLineBottom.addEventListener('mousemove', (event:any) => {
tip.style.left = (event.layerX + 8) + 'px' // tip.innerHTML = t('general.text.underline')
tip.style.top = (event.layerY + 18) + 'px' // tip.style.left = (event.layerX + 8) + 'px'
tip.style.display = 'block' // tip.style.top = (event.layerY + 18) + 'px'
}) // tip.style.display = 'block'
iconTextLineThrough.addEventListener('mouseleave', (event:any) => { // })
tip.style.display = 'none' // iconTextLineThrough.addEventListener('mouseleave', (event:any) => {
}) // tip.style.display = 'none'
iconTextLineThrough.addEventListener('mousemove', (event:any) => { // })
tip.innerHTML = t('general.text.strikethrough') // iconTextLineThrough.addEventListener('mousemove', (event:any) => {
tip.style.left = (event.layerX + 8) + 'px' // tip.innerHTML = t('general.text.strikethrough')
tip.style.top = (event.layerY + 18) + 'px' // tip.style.left = (event.layerX + 8) + 'px'
tip.style.display = 'block' // tip.style.top = (event.layerY + 18) + 'px'
}) // tip.style.display = 'block'
// })
} }
const closeCallback = () => { const closeCallback = () => {
@ -698,6 +700,7 @@ const confirm = () => {
baseDialog.value?.close() baseDialog.value?.close()
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
delete params.attribute.rtmp
let params2 = { let params2 = {
id: params.id, id: params.id,
sourceName: params.name, sourceName: params.name,
@ -812,10 +815,18 @@ defineExpose({
.attribute-content-link .table .tr .th:nth-child(2), .attribute-content-link .table .tr .th:nth-child(2),
.attribute-content-link .table .tr .td:nth-child(2), .attribute-content-link .table .tr .td:nth-child(2),
.attribute-content-vr .table .tr .th:nth-child(2), .attribute-content-vr .table .tr .th:nth-child(2),
.attribute-content-vr .table .tr .td:nth-child(2) { .attribute-content-vr .table .tr .td:nth-child(2),
.attribute-content-rtmp .table .tr .th:nth-child(2),
.attribute-content-rtmp .table .tr .td:nth-child(2) {
width: 284px; width: 284px;
flex: 0 0 284px; flex: 0 0 284px;
} }
.attribute-content-link .table .tr .td.operation button,
.attribute-content-vr .table .tr .td.operation button,
.attribute-content-rtmp .table .tr .td.operation button {
width: 76px !important;
flex: 0 0 76px !important;
}
} }
} }

View File

@ -1,12 +1,5 @@
<template> <template>
<Dialog <Dialog ref="baseDialog" title="曲线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback">
ref="baseDialog"
title="曲线标注"
left="180px"
top="100px"
className="polyline"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
@ -35,6 +28,84 @@
</div> </div>
</div> </div>
</div> </div>
<span class="custom-divider"></span>
<div class="div-item">
<setStyle type="折线" :sourceType="sourceType" :entityOptions="entityOptions"></setStyle>
<div class="row">
<div class="col">
<span class="label">线条颜色</span>
<div class="color" ref="colorRef"></div>
</div>
<div class="col" style="flex: 0 0 33%">
<span class="label">线条宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="1" max="999" @input="$handleInputLimit"
v-model="entityOptions.lineWidth" />
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
<div class="col input-select-line-type-box" style="flex: 0 0 37%">
<span class="label">线条形式</span>
<el-select class="input input-select input-select-line-type" style="margin-left: 20px"
v-model="entityOptions.lineType" @change="lineTypechange">
<el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key">
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
</el-option>
</el-select>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div>
<div class="col" style="flex: 0 0 33%">
<span class="label">缓冲宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" data-min="0.01" max="999999"
@input="$handleInputLimit" v-model="entityOptions.extendWidth" />
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col" style="flex: 0 0 37%">
<span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div>
</div>
</div>
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col">
<span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div>
<div class="col" style="flex: 0 0 33%">
<span class="label">流动速率</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input class="input" type="number" title="" min="0" max="999999" step="1" @input="$handleInputLimit"
v-model="entityOptions.speed" />
<span class="arrow"></span>
</div>
</div>
<div class="col" style="flex: 0 0 37%">
<span class="label lineSpace" v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span>
<div class="input-number input-number-unit-1 lineSpace" style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">
<input class="input" type="number" title="" min="0" max="4.5" step="0.1" @input="$handleInputLimit"
v-model="entityOptions.space" />
<span class="unit"></span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div>
</div>
</div>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<el-tabs v-model="activeName"> <el-tabs v-model="activeName">
@ -45,46 +116,22 @@
<div class="row"> <div class="row">
<div class="col height-mode-box"> <div class="col height-mode-box">
<span class="label" style="flex: 0 0 56px">高度模式</span> <span class="label" style="flex: 0 0 56px">高度模式</span>
<el-select <el-select class="input input-select height-mode-scelect" style="width: 155px; margin-left: 20px"
class="input input-select height-mode-scelect" v-model="heightMode" @change="heightModeChange" placeholder="请选择">
style="width: 155px; margin-left: 20px" <el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key">
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-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div <div class="input-number input-number-unit-1 height-box" :class="{ disabled: heightMode == 2 }">
class="input-number input-number-unit-1 height-box" <input class="input height" type="number" title="" min="-9999999" max="999999999"
:class="{ disabled: heightMode == 2 }" @input="$handleInputLimit" v-model="height" />
>
<input
class="input height"
type="number"
title=""
min="-9999999"
max="999999999"
@input="$handleInputLimit"
v-model="height"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button <button class="confirm height-confirm" style="margin-left: 5px" @click="heightConfirm"
class="confirm height-confirm" :disabled="heightMode == 2">
style="margin-left: 5px"
@click="heightConfirm"
:disabled="heightMode == 2"
>
应用 应用
</button> </button>
</div> </div>
@ -103,42 +150,21 @@
<div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i"> <div class="tr" v-for="(item, i) in entityOptions.options.positions" :key="i">
<div class="td">{{ i + 1 }}</div> <div class="td">{{ i + 1 }}</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')"> <div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')">
<input <input class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number"
class="input" v-model="item.lng" min="-180" max="180" @input="$handleInputLimit"
@blur="inputBlurCallBack($event, i, 'lng', 8)" v-if="activeTd.index == i && activeTd.name == 'lng'" />
type="number"
v-model="item.lng"
min="-180"
max="180"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span> <span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span>
</div> </div>
<div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')"> <div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')">
<input <input class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number"
class="input" v-model="item.lat" min="-180" max="180" @input="$handleInputLimit"
@blur="inputBlurCallBack($event, i, 'lat', 8)" v-if="activeTd.index == i && activeTd.name == 'lat'" />
type="number"
v-model="item.lat"
min="-180"
max="180"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span> <span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span>
</div> </div>
<div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')"> <div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')">
<input <input class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number"
class="input" v-model="item.alt" min="-9999999" max="999999999" @input="$handleInputLimit"
@blur="inputBlurCallBack($event, i, 'alt', 2)" v-if="activeTd.index == i && activeTd.name == 'alt'" />
type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'alt'"
/>
<span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span> <span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span>
</div> </div>
</div> </div>
@ -146,130 +172,7 @@
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="线条风格" name="3"> <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" style="flex: 0 0 33%">
<span class="label">线条宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input
class="input"
type="number"
title=""
min="1"
max="999"
@input="$handleInputLimit"
v-model="entityOptions.lineWidth"
/>
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
<div class="col input-select-line-type-box" style="flex: 0 0 37%">
<span class="label">线条形式</span>
<el-select
class="input input-select input-select-line-type"
style="margin-left: 20px"
v-model="entityOptions.lineType"
@change="lineTypechange"
>
<el-option
v-for="item in lineTypeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
<i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }}
</el-option>
</el-select>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div>
<div class="col" style="flex: 0 0 33%">
<span class="label">缓冲宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input
class="input"
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
@input="$handleInputLimit"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span>
<span class="arrow"></span>
</div>
</div>
<div class="col" style="flex: 0 0 37%">
<span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div>
</div>
</div>
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col">
<span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div>
<div class="col" style="flex: 0 0 33%">
<span class="label">流动速率</span>
<div class="input-number input-number-unit-1" style="width: 80px">
<input
class="input"
type="number"
title=""
min="0"
max="999999"
step="1"
@input="$handleInputLimit"
v-model="entityOptions.speed"
/>
<span class="arrow"></span>
</div>
</div>
<div class="col" style="flex: 0 0 37%">
<span
class="label lineSpace"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
>线条间距</span
>
<div
class="input-number input-number-unit-1 lineSpace"
style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
>
<input
class="input"
type="number"
title=""
min="0"
max="4.5"
step="0.1"
@input="$handleInputLimit"
v-model="entityOptions.space"
/>
<span class="unit"></span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div>
</div>
</el-tab-pane>
<el-tab-pane label="标签风格" name="4">
<labelStyle type="线" :entityOptions="entityOptions"></labelStyle> <labelStyle type="线" :entityOptions="entityOptions"></labelStyle>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@ -280,7 +183,8 @@
<div style="position: absolute; left: 24px; display: flex"> <div style="position: absolute; left: 24px; display: flex">
<button @click="nodeEdit"> <button @click="nodeEdit">
<svg class="icon-edit"> <svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use></svg>二次编辑 <use xlink:href="#yj-icon-edit"></use>
</svg>二次编辑
</button> </button>
<button style="margin-left: 10px" @click="translate">平移</button> <button style="margin-left: 10px" @click="translate">平移</button>
</div> </div>
@ -300,6 +204,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { getFontList } from './fontSelect' import { getFontList } from './fontSelect'
import attribute from './attribute.vue' import attribute from './attribute.vue'
import setStyle from './defaultStyle/index.vue'
import labelStyle from './labelStyle.vue' import labelStyle from './labelStyle.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode' import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
@ -309,6 +214,7 @@ const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
const baseDialog: any = ref(null) const baseDialog: any = ref(null)
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
const sourceType = ref('')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
const fontList = ref(getFontList()) const fontList = ref(getFontList())
@ -425,8 +331,9 @@ const wordsName = ref(0)
let originalOptions let originalOptions
let that let that
const open = async (id) => { const open = async (id, type) => {
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
sourceType.value = type
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
entityOptions.value = that entityOptions.value = that
wordsName.value = Number(entityOptions.value.wordsName) wordsName.value = Number(entityOptions.value.wordsName)

View File

@ -0,0 +1,126 @@
<template>
<div class="row">
<div class="col">
<span class="lable-left-line">新增{{ props.type }}标签风格设置</span>
<div style="display: flex;align-items: center;margin-right: 30px;">
<button style="margin-right: 10px;" @click="setInitialStyle">初始风格</button>
<el-tooltip effect="customized" :hide-after="0" placement="top">
<template #content>初始系统默认的{{ props.type }}标签风格<br />点击初始风格按钮{{ props.type }}系统初始风格设置为新增{{ props.type
}}的标签风格</template>
<svg class="icon-prompt">
<use xlink:href="#icon-prompt"></use>
</svg>
</el-tooltip>
</div>
<div style="display: flex;align-items: center;">
<button style="margin-right: 10px;" @click="setCurrentStyle">当前风格</button>
<el-tooltip effect="customized" :hide-after="0" placement="top">
<template #content>当前面板设置的{{ props.type }}标签风格<br />点击当前风格按钮{{ props.type }}当前面板风格设置为新增{{ props.type
}}的标签风格</template>
<svg class="icon-prompt">
<use xlink:href="#icon-prompt"></use>
</svg>
</el-tooltip>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { getdefaultLabelStyle } from './style'
const props = defineProps({
type: {
type: String,
default: ''
},
sourceType: {
type: String,
default: ''
},
entityOptions: {
type: Object,
default: {}
}
})
const setInitialStyle = () => {
let style = getdefaultLabelStyle(props.sourceType)
let defaultStyle = JSON.parse(localStorage.getItem('defaultStyle') || '{}')
defaultStyle[props.sourceType] = style
localStorage.setItem('defaultStyle', JSON.stringify(defaultStyle))
ElMessage({
message: `新增${props.type}风格设置成功!`,
type: "success",
});
}
const setCurrentStyle = () => {
let options = props.entityOptions.options
let defaultStyle = JSON.parse(localStorage.getItem('defaultStyle') || '{}')
switch (props.sourceType) {
case 'point':
defaultStyle[props.sourceType] = {
billboard: {
show: options.billboard.show,
image: options.billboard.image,
scale: options.billboard.scale,
},
label: {
show: options.label.show,
fontSize: options.label.fontSize,
color: options.label.color,
fontFamily: options.label.fontFamily,
}
}
break
case 'line':
defaultStyle[props.sourceType] = {
color: options.color,
width: options.width,
type: options.type,
noseToTail: options.noseToTail,
smooth: options.smooth,
extend: options.extend,
extendWidth: options.extendWidth,
extendColor: options.extendColor,
rotate: options.rotate,
speed: options.speed,
space: options.space,
}
break
case 'curve':
defaultStyle[props.sourceType] = {
color: options.color,
width: options.width,
type: options.type,
noseToTail: options.noseToTail,
extend: options.extend,
extendWidth: options.extendWidth,
extendColor: options.extendColor,
rotate: options.rotate,
speed: options.speed,
space: options.space,
}
break
}
localStorage.setItem('defaultStyle', JSON.stringify(defaultStyle))
ElMessage({
message: `新增${props.type}风格设置成功!`,
type: "success",
});
}
</script>
<style scoped>
.lable-left-line {
margin-right: 10px;
}
.icon-prompt {
fill: rgba(241, 108, 85, 1) !important;
width: 16px;
height: 16px;
margin: 0;
}
</style>

View File

@ -0,0 +1,12 @@
let defaultLabelStyle = {
point: {
},
line: {
},
curve: {
}
}
//@ts-ignore
export const getdefaultLabelStyle = (type) => {
return (type ? defaultLabelStyle[type] : defaultLabelStyle)
}

View File

@ -4,9 +4,9 @@
<span class="lable-left-line">新增{{ props.type }}风格设置</span> <span class="lable-left-line">新增{{ props.type }}风格设置</span>
<div style="display: flex;align-items: center;margin-right: 30px;"> <div style="display: flex;align-items: center;margin-right: 30px;">
<button style="margin-right: 10px;" @click="setInitialStyle">初始风格</button> <button style="margin-right: 10px;" @click="setInitialStyle">初始风格</button>
<el-tooltip <el-tooltip effect="customized" :hide-after="0" placement="top">
effect="customized" :hide-after="0" placement="top"> <template #content>初始系统默认的{{ props.type }}风格<br />点击初始风格按钮{{ props.type }}系统初始风格设置为新增{{ props.type
<template #content>初始系统默认的{{props.type}}风格<br />点击初始风格按钮{{props.type}}系统初始风格设置为新增{{props.type}}风格</template> }}风格</template>
<svg class="icon-prompt"> <svg class="icon-prompt">
<use xlink:href="#icon-prompt"></use> <use xlink:href="#icon-prompt"></use>
</svg> </svg>
@ -14,10 +14,10 @@
</div> </div>
<div style="display: flex;align-items: center;"> <div style="display: flex;align-items: center;">
<button style="margin-right: 10px;">当前风格</button> <button style="margin-right: 10px;" @click="setCurrentStyle">当前风格</button>
<el-tooltip <el-tooltip effect="customized" :hide-after="0" placement="top">
effect="customized" :hide-after="0" placement="top"> <template #content>当前面板设置的{{ props.type }}风格<br />点击当前风格按钮{{ props.type }}当前面板风格设置为新增{{ props.type
<template #content>当前面板设置的{{props.type}}风格<br />点击当前风格按钮{{props.type}}当前面板风格设置为新增{{props.type}}风格</template> }}风格</template>
<svg class="icon-prompt"> <svg class="icon-prompt">
<use xlink:href="#icon-prompt"></use> <use xlink:href="#icon-prompt"></use>
</svg> </svg>
@ -50,6 +50,65 @@ const setInitialStyle = () => {
let defaultStyle = JSON.parse(localStorage.getItem('defaultStyle') || '{}') let defaultStyle = JSON.parse(localStorage.getItem('defaultStyle') || '{}')
defaultStyle[props.sourceType] = style defaultStyle[props.sourceType] = style
localStorage.setItem('defaultStyle', JSON.stringify(defaultStyle)) localStorage.setItem('defaultStyle', JSON.stringify(defaultStyle))
ElMessage({
message: `新增${props.type}风格设置成功!`,
type: "success",
});
}
const setCurrentStyle = () => {
let options = props.entityOptions.options
let defaultStyle = JSON.parse(localStorage.getItem('defaultStyle') || '{}')
switch (props.sourceType) {
case 'point':
defaultStyle[props.sourceType] = {
billboard: {
show: options.billboard.show,
image: options.billboard.image,
scale: options.billboard.scale,
},
label: {
show: options.label.show,
fontSize: options.label.fontSize,
color: options.label.color,
fontFamily: options.label.fontFamily,
}
}
break
case 'line':
defaultStyle[props.sourceType] = {
color: options.color,
width: options.width,
type: options.type,
noseToTail: options.noseToTail,
smooth: options.smooth,
extend: options.extend,
extendWidth: options.extendWidth,
extendColor: options.extendColor,
rotate: options.rotate,
speed: options.speed,
space: options.space,
}
break
case 'curve':
defaultStyle[props.sourceType] = {
color: options.color,
width: options.width,
type: options.type,
noseToTail: options.noseToTail,
extend: options.extend,
extendWidth: options.extendWidth,
extendColor: options.extendColor,
rotate: options.rotate,
speed: options.speed,
space: options.space,
}
break
}
localStorage.setItem('defaultStyle', JSON.stringify(defaultStyle))
ElMessage({
message: `新增${props.type}风格设置成功!`,
type: "success",
});
} }
</script> </script>

View File

@ -3,11 +3,9 @@ let availablePort = 55110
ipcRenderer.invoke('get-available-port').then((port) => { ipcRenderer.invoke('get-available-port').then((port) => {
availablePort = port availablePort = port
}) })
//@ts-ignore
export const getdefaultStyle = (type) => { let defaultStyle = {
switch (type) { point: {
case 'point':
return {
billboard: { billboard: {
show: true, show: true,
image: "http://localhost:" + image: "http://localhost:" +
@ -20,18 +18,36 @@ export const getdefaultStyle = (type) => {
show: true, show: true,
fontSize: 39, fontSize: 39,
color: 'rgba(0, 255, 255, 1)', color: 'rgba(0, 255, 255, 1)',
fontFamily: 'Helvetica', fontFamily: 0,
} }
} },
case 'line': line: {
return { color: '#ff0000',
color: 'rgba(241, 108, 85, 1)', width: 3,
fontSize: 12, type: 0,
fontName: '微软雅黑', noseToTail: false,
fontWeight: '400', smooth: false,
fontStyle: 'normal', extend: false,
textDecoration: 'none', extendWidth: 10,
background: 'rgba(0, 0, 0, 0.5)', extendColor: "rgba(255,255,80,0.3)",
rotate: true,
speed: 10,
space: 1
},
curve: {
color: '#ff0000',
width: 3,
type: 0,
noseToTail: false,
extend: false,
extendWidth: 10,
extendColor: "rgba(255,255,80,0.3)",
rotate: true,
speed: 10,
space: 1
} }
} }
//@ts-ignore
export const getdefaultStyle = (type) => {
return (type ? defaultStyle[type] : defaultStyle)
} }

View File

@ -916,6 +916,32 @@ function attributeElm(that) {
</div> </div>
</div> </div>
</div> </div>
<div class="row attribute-content attribute-content-rtmp">
<div class="col">
<span class="label">添加链接</span>
<div style="flex: 1;position: relative;">
<input class="input rtmp_add" type="text">
<i class="rtmp_add_btn" @click="_addRtmp"></i>
</div>
</div>
</div>
<div class="attribute-content attribute-content-rtmp">
<div class="table">
<div class="table-head">
<div class="tr">
<div class="th">名称</div>
<div class="th">链接</div>
<div class="th">操作</div>
</div>
</div>
<div class="table-body">
</div>
<div class="table-empty">
<div class="empty-img"></div>
<p>暂无数据</p>
</div>
</div>
</div>
<div class="attribute-content attribute-content-goods"> <div class="attribute-content attribute-content-goods">
<div> <div>
<div class="row"> <div class="row">

View File

@ -1,6 +1,8 @@
<template> <template>
<div> <div>
<div class="row"></div> <div class="row">
<setLabelStyle :type="type" :entityOptions="entityOptions" />
</div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label" style="margin-right: 42px">标签设置</span> <span class="label" style="margin-right: 42px">标签设置</span>
@ -16,15 +18,8 @@
<div class="col"> <div class="col">
<span class="label">最近距离</span> <span class="label">最近距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input class="input" type="number" title="" min="1" max="99999999" @input="$handleInputLimit"
class="input" v-model="entityOptions.labelNear" />
type="number"
title=""
min="1"
max="99999999"
@input="$handleInputLimit"
v-model="entityOptions.labelNear"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -32,15 +27,8 @@
<div class="col"> <div class="col">
<span class="label">最远距离</span> <span class="label">最远距离</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input <input class="input" type="number" title="" min="1" max="99999999" @input="$handleInputLimit"
class="input" v-model="entityOptions.labelFar" />
type="number"
title=""
min="1"
max="99999999"
@input="$handleInputLimit"
v-model="entityOptions.labelFar"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -54,22 +42,15 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px"> <div class="col">
<span class="label">字体颜色</span> <span class="label">字体颜色</span>
<div class="labelColor" ref="labelColorRef"></div> <div class="labelColor" ref="labelColorRef"></div>
</div> </div>
<div class="col"> <div class="col">
<span class="label">字体大小</span> <span class="label">字体大小</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input <input class="input" type="number" title="" min="1" max="99" @input="$handleInputLimit"
class="input" v-model="entityOptions.labelFontSize" />
type="number"
title=""
min="1"
max="99"
@input="$handleInputLimit"
v-model="entityOptions.labelFontSize"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -82,12 +63,52 @@
</el-select> </el-select>
</div> </div>
</div> </div>
<!-- <div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px;"> <div class="col">
<span class="label">轮廓颜色</span> <div class="customized-tip"></div>
<div class="outlineColor"></div> <span class="label" style="flex: none;">{{ t('general.text.style') }}</span>
<svg class="icon-text bold">
<use xlink:href="#icon-text-bold"></use>
</svg>
<svg class="icon-text italic">
<use xlink:href="#icon-text-italic"></use>
</svg>
<svg class="icon-text line-bottom">
<use xlink:href="#icon-text-line-bottom"></use>
</svg>
<svg class="icon-text line-through">
<use xlink:href="#icon-text-line-through"></use>
</svg>
</div> </div>
</div> --> <div class="col">
<span class="label" style="flex: none;">{{ t('general.text.letterSpacing') }}</span>
<div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="0" max="99" style="min-width: 70px;"
@input="$handleInputLimit" />
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
<div class="col"></div>
</div>
<div class="row">
<div class="col">
<span class="label" style="flex: none;">{{ t('general.outline.color') }}</span>
<div class="labelOutlineColorColor" ref="labelOutlineColorRef"></div>
</div>
<div class="col">
<span class="label" style="flex: none;">{{ t('general.outline.width') }}</span>
<div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="0" max="99" style="min-width: 70px;"
@input="$handleInputLimit" />
<span class="unit">px</span>
<span class="arrow"></span>
</div>
</div>
<div class="col"></div>
</div>
<span class="custom-divider"></span>
<div class="row"></div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">标签样式</span> <span class="label">标签样式</span>
@ -115,15 +136,8 @@
<div class="col"> <div class="col">
<span class="label">引线宽度</span> <span class="label">引线宽度</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input <input class="input" type="number" title="" min="1" max="999" @input="$handleInputLimit"
class="input" v-model="entityOptions.labelLineWidth" />
type="number"
title=""
min="1"
max="999"
@input="$handleInputLimit"
v-model="entityOptions.labelLineWidth"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -131,15 +145,8 @@
<div class="col"> <div class="col">
<span class="label">引线长度</span> <span class="label">引线长度</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input <input class="input" type="number" title="" min="0" max="999" @input="$handleInputLimit"
class="input" v-model="entityOptions.labelPixelOffset" />
type="number"
title=""
min="0"
max="999"
@input="$handleInputLimit"
v-model="entityOptions.labelPixelOffset"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -152,6 +159,9 @@
import { ref } from 'vue' import { ref } from 'vue'
import { inject } from 'vue' import { inject } from 'vue'
import { getFontList } from './fontSelect' import { getFontList } from './fontSelect'
import setLabelStyle from './defaultLabelStyle/index.vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const props = defineProps({ const props = defineProps({
type: { type: {

View File

@ -361,7 +361,7 @@ const modelClick = (index, row) => {
} else if (butActiveIndex.value === 1) { } else if (butActiveIndex.value === 1) {
selectedImg = 'http://localhost:' + availablePort.value + '/' + row.data selectedImg = 'http://localhost:' + availablePort.value + '/' + row.data
} else if (butActiveIndex.value === 2) { } else if (butActiveIndex.value === 2) {
selectedImg = service.value + row.data selectedImg = service.value + row.iconDataUrl
} }
selectCallback(selectedImg) selectCallback(selectedImg)
} }

View File

@ -1,12 +1,5 @@
<template> <template>
<Dialog <Dialog ref="baseDialog" title="线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback">
ref="baseDialog"
title="线标注"
left="180px"
top="100px"
className="polyline"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
@ -35,118 +28,9 @@
</div> </div>
</div> </div>
</div> </div>
<span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row"> <setStyle type="线" :sourceType="sourceType" :entityOptions="entityOptions"></setStyle>
<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"
@input="$handleInputLimit"
/>
<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" v-for="(item, i) in entityOptions.options.positions" :key="i">
<div class="td">{{ i + 1 }}</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')">
<input
class="input"
@blur="inputBlurCallBack($event, i, 'lng', 8)"
type="number"
v-model="item.lng"
min="-180"
max="180"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span>
</div>
<div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')">
<input
class="input"
@blur="inputBlurCallBack($event, i, 'lat', 8)"
type="number"
v-model="item.lat"
min="-180"
max="180"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span>
</div>
<div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')">
<input
class="input"
@blur="inputBlurCallBack($event, i, 'alt', 2)"
type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
@input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'alt'"
/>
<span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="线条风格" name="3">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">线条颜色</span> <span class="label">线条颜色</span>
@ -155,33 +39,17 @@
<div class="col" style="flex: 0 0 33%"> <div class="col" style="flex: 0 0 33%">
<span class="label">线条宽度</span> <span class="label">线条宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px"> <div class="input-number input-number-unit-1" style="width: 80px">
<input <input class="input" type="number" title="" min="1" max="999" @input="$handleInputLimit"
class="input" v-model="entityOptions.lineWidth" />
type="number"
title=""
min="1"
max="999"
@input="$handleInputLimit"
v-model="entityOptions.lineWidth"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col input-select-line-type-box" style="flex: 0 0 37%"> <div class="col input-select-line-type-box" style="flex: 0 0 37%">
<span class="label">线条形式</span> <span class="label">线条形式</span>
<el-select <el-select class="input input-select input-select-line-type" style="margin-left: 20px"
class="input input-select input-select-line-type" v-model="entityOptions.lineType" @change="lineTypechange">
style="margin-left: 20px" <el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key">
v-model="entityOptions.lineType"
@change="lineTypechange"
>
<el-option
v-for="item in lineTypeData"
:key="item.key"
:label="item.name"
:value="item.key"
>
<i class="yj-custom-icon" :class="item.icon"></i> <i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }} {{ item.name }}
</el-option> </el-option>
@ -207,16 +75,8 @@
<div class="col" style="flex: 0 0 33%"> <div class="col" style="flex: 0 0 33%">
<span class="label">缓冲宽度</span> <span class="label">缓冲宽度</span>
<div class="input-number input-number-unit-1" style="width: 80px"> <div class="input-number input-number-unit-1" style="width: 80px">
<input <input class="input" type="number" title="" min="0" data-min="0.01" max="999999"
class="input" @input="$handleInputLimit" v-model="entityOptions.extendWidth" />
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
@input="$handleInputLimit"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -234,62 +94,108 @@
<div class="col" style="flex: 0 0 33%"> <div class="col" style="flex: 0 0 33%">
<span class="label">流动速率</span> <span class="label">流动速率</span>
<div class="input-number input-number-unit-1" style="width: 80px"> <div class="input-number input-number-unit-1" style="width: 80px">
<input <input class="input" type="number" title="" min="0" max="999999" step="1" @input="$handleInputLimit"
class="input" v-model="entityOptions.speed" />
type="number"
title=""
min="0"
max="999999"
step="1"
@input="$handleInputLimit"
v-model="entityOptions.speed"
/>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 37%"> <div class="col" style="flex: 0 0 37%">
<span <span class="label lineSpace" v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span>
class="label lineSpace" <div class="input-number input-number-unit-1 lineSpace" style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5" v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">
>线条间距</span <input class="input" type="number" title="" min="0" max="4.5" step="0.1" @input="$handleInputLimit"
> v-model="entityOptions.space" />
<div
class="input-number input-number-unit-1 lineSpace"
style="width: 80px"
v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5"
>
<input
class="input"
type="number"
title=""
min="0"
max="4.5"
step="0.1"
@input="$handleInputLimit"
v-model="entityOptions.space"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</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>
<el-tab-pane label="标签风格" name="4"> <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"
@input="$handleInputLimit" />
<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" v-for="(item, i) in entityOptions.options.positions" :key="i">
<div class="td">{{ i + 1 }}</div>
<div class="td lng align-center" @dblclick="inputDblclick($event, i, 'lng')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number"
v-model="item.lng" min="-180" max="180" @input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lng'" />
<span style="pointer-events: none" v-else>{{ item.lng.toFixed(8) }}</span>
</div>
<div class="td lat align-center" @dblclick="inputDblclick($event, i, 'lat')">
<input class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number"
v-model="item.lat" min="-180" max="180" @input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'lat'" />
<span style="pointer-events: none" v-else>{{ item.lat.toFixed(8) }}</span>
</div>
<div class="td alt align-center" @dblclick="inputDblclick($event, i, 'alt')">
<input class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number"
v-model="item.alt" min="-9999999" max="999999999" @input="$handleInputLimit"
v-if="activeTd.index == i && activeTd.name == 'alt'" />
<span style="pointer-events: none" v-else>{{ item.alt.toFixed(2) }}</span>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="标签风格" name="3">
<labelStyle type="线" :entityOptions="entityOptions"></labelStyle> <labelStyle type="线" :entityOptions="entityOptions"></labelStyle>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
<span class="custom-divider"></span>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex"> <div style="position: absolute; left: 24px; display: flex">
<button @click="nodeEdit"> <button @click="nodeEdit">
<svg class="icon-edit"> <svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use></svg>二次编辑 <use xlink:href="#yj-icon-edit"></use>
</svg>二次编辑
</button> </button>
<button style="margin-left: 10px" @click="translate"> <button style="margin-left: 10px" @click="translate">
<svg class="icon-py"> <svg class="icon-py">
<use xlink:href="#yj-icon-py"></use></svg>平移 <use xlink:href="#yj-icon-py"></use>
</svg>平移
</button> </button>
</div> </div>
<button @click="remove">删除</button> <button @click="remove">删除</button>
@ -307,6 +213,7 @@ import { TreeApi } from '@/api/tree'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import attribute from './attribute.vue' import attribute from './attribute.vue'
import setStyle from './defaultStyle/index.vue'
import labelStyle from './labelStyle.vue' import labelStyle from './labelStyle.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode' import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
@ -316,6 +223,7 @@ const { cusUpdateNode, getSelectedNodes, cusRemoveNode } = useTreeNode()
const baseDialog: any = ref(null) const baseDialog: any = ref(null)
const eventBus: any = inject('bus') const eventBus: any = inject('bus')
const sourceType = ref('')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
const height = ref(10) const height = ref(10)
@ -431,8 +339,9 @@ const wordsName = ref(0)
let originalOptions: any let originalOptions: any
let that: any let that: any
const open = async (id: any) => { const open = async (id: any, type) => {
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
sourceType.value = type
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
entityOptions.value = that entityOptions.value = that
heightMode.value = entityOptions.value.heightMode heightMode.value = entityOptions.value.heightMode

View File

@ -52,6 +52,11 @@ function leftClick(options) {
? options.attribute.vr.content ? options.attribute.vr.content
: [] : []
: [], : [],
rtmp: options.attribute
? options.attribute.rtmp
? options.attribute.rtmp.content
: []
: [],
goods: options.attribute goods: options.attribute
? options.attribute.goods ? options.attribute.goods
? options.attribute.goods.content ? options.attribute.goods.content
@ -79,6 +84,7 @@ function leftClick(options) {
!options.richTextContent && !options.richTextContent &&
!info.hrefs.length && !info.hrefs.length &&
!info.vr.length && !info.vr.length &&
!info.rtmp.length &&
!info.goods.length && !info.goods.length &&
!info.camera.length !info.camera.length
) { ) {
@ -96,7 +102,6 @@ function leftClick(options) {
) { ) {
tankuang(id, node, info); tankuang(id, node, info);
} }
console.log('info.camera', info.camera)
if (info.camera && info.camera.length) { if (info.camera && info.camera.length) {
if (index == 0) { if (index == 0) {
ElMessage.success("摄像头打开中请稍后"); ElMessage.success("摄像头打开中请稍后");
@ -161,6 +166,50 @@ function leftClick(options) {
} }
//if (info.type == "vr") //if (info.type == "vr")
} }
if (info.rtmp && info.rtmp.length) {
let isExistent = false
let isNoExistent = false
for(let i=0;i<info.rtmp.length;i++) {
if(!(window as any)._winMap.has(info.rtmp[i].id)) {
isNoExistent = true;
(window as any)._winMap.set(info.rtmp[i].id, info.rtmp[i].id);
ipcRenderer.send("openFFPlay", {
id: info.rtmp[i].id,
url: info.rtmp[i].url,
name: info.rtmp[i].name,
});
ipcRenderer.once(
"openFFPlayOut_"+info.rtmp[i].id,
(e, err, id) => {
if (err) {
ElMessage({
message: "视频流错误,打开失败!",
type: "error",
});
}
if(id) {
(window as any)._winMap.delete(id);
}
}
);
}
else {
isExistent = true
}
}
if(isNoExistent) {
ElMessage({
message: "视频流打开中请稍后",
type: "success",
});
}
if(isExistent) {
ElMessage({
message: "视频已打开",
type: "info",
});
}
}
} }
} }
} }

View File

@ -178,12 +178,12 @@ eventBus.on('openDialog', async (sourceType: any, id: any) => {
case 'line': case 'line':
currentComponent.value = polylineObject currentComponent.value = polylineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id, sourceType)
break break
case 'curve': case 'curve':
currentComponent.value = curvelineObject currentComponent.value = curvelineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id, sourceType)
break break
case 'panel': case 'panel':
currentComponent.value = polygonObject currentComponent.value = polygonObject
@ -455,30 +455,30 @@ const createEarth = async () => {
window.earth = await new YJ.YJEarth('earthContainer') window.earth = await new YJ.YJEarth('earthContainer')
let openLeftClick = await new YJ.Global.openLeftClick(window.earth) let openLeftClick = await new YJ.Global.openLeftClick(window.earth)
let openRightClick = await new YJ.Global.openRightClick(window.earth) let openRightClick = await new YJ.Global.openRightClick(window.earth)
YJ.Global.MouseRightMenu(window.earth, true, (text, object) => { // YJ.Global.MouseRightMenu(window.earth, true, (text, object) => {
switch (text) { // switch (text) {
case 'rotateAround': // case 'rotateAround':
YJ.Global.rotateAround(window.earth, object.position) // YJ.Global.rotateAround(window.earth, object.position)
break // break
case 'textBox': // case 'textBox':
let id = new YJ.Tools().randomString() // let id = new YJ.Tools().randomString()
let name = '文本框' // let name = '文本框'
addMapSource({ // addMapSource({
type: 'textBox', // type: 'textBox',
id: id, // id: id,
sourceName: name, // sourceName: name,
opt: { // opt: {
id: id, // id: id,
position: object.position // position: object.position
} // }
}) // })
break // break
case 'attribute': // case 'attribute':
let node = window.treeObj.getNodeByParam('id', object.id, null) // let node = window.treeObj.getNodeByParam('id', object.id, null)
rightMenus.edit.callback(eventBus, node) // rightMenus.edit.callback(eventBus, node)
break // break
} // }
}) // })
tree.value.initTreeCallBack() tree.value.initTreeCallBack()
utilsSysChange(eventBus) utilsSysChange(eventBus)