This commit is contained in:
2025-09-05 19:18:46 +08:00
25 changed files with 2165 additions and 819 deletions

View File

@ -4,5 +4,7 @@ declare global {
interface Window { interface Window {
electron: ElectronAPI electron: ElectronAPI
api: unknown api: unknown
Cesium: any
YJColorPicker: any
} }
} }

View File

@ -18,4 +18,8 @@ if (process.contextIsolated) {
window.electron = electronAPI window.electron = electronAPI
// @ts-ignore (define in dts) // @ts-ignore (define in dts)
window.electronAPI = api window.electronAPI = api
// @ts-ignore (define in dts)
window.Cesium = Cesium
// @ts-ignore (define in dts)
window.YJColorPicker = YJColorPicker
} }

View File

@ -9,14 +9,12 @@ export {}
declare module 'vue' { declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
BaseDialog: typeof import('./src/components/dialog/baseDialog.vue')['default'] BaseDialog: typeof import('./src/components/dialog/baseDialog.vue')['default']
Dialog: typeof import('./src/components/dialog/index.vue')['default']
Directory: typeof import('./src/components/dialog/directory.vue')['default'] Directory: typeof import('./src/components/dialog/directory.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElForm: typeof import('element-plus/es')['ElForm'] ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput'] ElInput: typeof import('element-plus/es')['ElInput']
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']

View File

@ -12,13 +12,18 @@ export const TreeApi = {
return await request.post({ return await request.post({
url: `/source/addOtherSource`, url: `/source/addOtherSource`,
data data
}).then((res) => {
ElMessage({
message: '添加成功',
type: 'success'
})
}) })
}, },
//新增节点 //新增目录
addDirectory: async (data: any) => { addDirectory: async (data: any) => {
return await request.post({ return await request.post({
url: `/source/addOtherSource`, url: `/source/addDirectory`,
data data
}).then((res) => { }).then((res) => {
ElMessage({ ElMessage({

View File

@ -1,12 +1,22 @@
<template> <template>
<div class="YJ-custom-base-dialog" :class="className" ref="baseDialog" :id="id" :style="{ <div
class="YJ-custom-base-dialog"
:class="className"
ref="baseDialog"
:id="id"
:style="{
width: width, width: width,
height: height, height: height,
position: fix ? 'fixed' : 'absolute' position: fix ? 'fixed' : 'absolute'
}" v-if="dialogVisible" v-show="dialogVisible"> }"
<div class="title-box" ref="titleBox"><span class="title">{{ title }}</span><span class="close-box" v-if="dialogVisible"
@click="close"><span class="close"></span><i></i></span></div> v-show="dialogVisible"
<div class="content" style="padding: 0 24px 0 24px;"> >
<div class="title-box" ref="titleBox">
<span class="title">{{ title }}</span
><span class="close-box" @click="close"><span class="close"></span><i></i></span>
</div>
<div class="content" style="padding: 0 24px 0 24px">
<div> <div>
<slot name="content"></slot> <slot name="content"></slot>
</div> </div>
@ -18,237 +28,233 @@
</template> </template>
<script setup> <script setup>
import { ref, watch, onMounted, nextTick } from 'vue'; import { ref, watch, onMounted, nextTick } from 'vue'
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: "", default: ''
}, },
width: { width: {
type: String, type: String,
default: "", default: ''
}, },
height: { height: {
type: String, type: String,
default: "", default: ''
}, },
top: { top: {
type: String, type: String,
default: "", default: ''
}, },
left: { left: {
type: String, type: String,
default: "", default: ''
}, },
id: { id: {
type: String, type: String,
default: "", default: ''
}, },
bodyId: { bodyId: {
type: String, type: String,
default: "", default: ''
}, },
clearAnimation: { clearAnimation: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
fix: { fix: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
className: { className: {
type: String, type: String
}, },
nofold: { nofold: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
isfold: { isfold: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
noClose: { noClose: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
show: { show: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
closeCallback: { closeCallback: {
type: Function, type: Function,
default: () => { }, default: () => {}
} }
}); })
// 内部状态 // 内部状态
const first = ref(false); const first = ref(false)
const dialogVisible = ref(false); const dialogVisible = ref(false)
const FontChart = ref(undefined); const FontChart = ref(undefined)
const callback = ref(undefined); const callback = ref(undefined)
const baseDialog = ref(null); const baseDialog = ref(null)
const titleBox = ref(null); const titleBox = ref(null)
const dialogContent = ref(null); const dialogContent = ref(null)
const tableData = ref([]); const tableData = ref([])
// 监听show属性变化 // 监听show属性变化
watch( watch(
() => props.show, () => props.show,
(val) => { (val) => {
dialogVisible.value = val; dialogVisible.value = val
}, },
{ immediate: true } { immediate: true }
); )
// 组件挂载后执行 // 组件挂载后执行
onMounted(() => { onMounted(() => {
// 可以在这里添加初始化逻辑 // 可以在这里添加初始化逻辑
}); })
// 方法定义 // 方法定义
const open = (data) => { const open = (data) => {
if (!first.value) { if (!first.value) {
first.value = true; first.value = true
dialogVisible.value = true; dialogVisible.value = true
nextTick(() => { nextTick(() => {
moveDiv(); moveDiv()
}); })
} }
dialogVisible.value = true; dialogVisible.value = true
nextTick(() => { nextTick(() => {
setTimeout(() => { setTimeout(() => {
openPosition(); openPosition()
}, 0); }, 0)
}); })
}; }
const close = () => { const close = () => {
dialogVisible.value = false; dialogVisible.value = false
if (props.clearAnimation) { if (props.clearAnimation) {
// 假设mapService是全局可用的 // 假设mapService是全局可用的
window.mapService?.removeAnimation(); window.mapService?.removeAnimation()
} }
callback.value && callback.value(); callback.value && callback.value()
props.closeCallback && props.closeCallback() props.closeCallback && props.closeCallback()
}; }
const moveDiv = () => { const moveDiv = () => {
let x = 0; let x = 0
let y = 0; let y = 0
let l = 0; let l = 0
let t = 0; let t = 0
const oClickDiv = baseDialog.value; const oClickDiv = baseDialog.value
const oMoveDiv = titleBox.value; const oMoveDiv = titleBox.value
if (oClickDiv) { if (oClickDiv) {
console.log(oMoveDiv) console.log(oMoveDiv)
oMoveDiv.onmousedown = (e) => { oMoveDiv.onmousedown = (e) => {
// 获取对话框尺寸 // 获取对话框尺寸
const oMoveDivHeight = baseDialog.value.offsetHeight; const oMoveDivHeight = baseDialog.value.offsetHeight
const oMoveDivWidth = baseDialog.value.offsetWidth; const oMoveDivWidth = baseDialog.value.offsetWidth
x = e.clientX; x = e.clientX
y = e.clientY; y = e.clientY
const leftPx = window.getComputedStyle(baseDialog.value).left; const leftPx = window.getComputedStyle(baseDialog.value).left
const topPx = window.getComputedStyle(baseDialog.value).top; const topPx = window.getComputedStyle(baseDialog.value).top
l = parseFloat(leftPx); l = parseFloat(leftPx)
t = parseFloat(topPx); t = parseFloat(topPx)
// 获取视口大小 // 获取视口大小
const container = props.bodyId const container = props.bodyId ? document.getElementById(props.bodyId) : document.body
? document.getElementById(props.bodyId) const windowHeight = container.clientHeight
: document.body; const windowWidth = container.clientWidth
const windowHeight = container.clientHeight;
const windowWidth = container.clientWidth;
// 鼠标移动事件处理 // 鼠标移动事件处理
const handleMouseMove = (e) => { const handleMouseMove = (e) => {
e.preventDefault(); e.preventDefault()
const nx = e.clientX; const nx = e.clientX
const ny = e.clientY; const ny = e.clientY
// 计算新位置 // 计算新位置
let newLeft = nx - (x - l); let newLeft = nx - (x - l)
let newTop = ny - (y - t); let newTop = ny - (y - t)
// 边界检查 // 边界检查
if (newLeft < 0) { if (newLeft < 0) {
newLeft = 0; newLeft = 0
} else if (newLeft + oMoveDivWidth > windowWidth) { } else if (newLeft + oMoveDivWidth > windowWidth) {
newLeft = windowWidth - oMoveDivWidth; newLeft = windowWidth - oMoveDivWidth
} }
if (newTop <= 0) { if (newTop <= 0) {
newTop = 0; newTop = 0
} else if (newTop + oMoveDivHeight > windowHeight) { } else if (newTop + oMoveDivHeight > windowHeight) {
newTop = windowHeight - oMoveDivHeight; newTop = windowHeight - oMoveDivHeight
} }
// 更新位置 // 更新位置
if (baseDialog.value) { if (baseDialog.value) {
baseDialog.value.style.left = newLeft + "px"; baseDialog.value.style.left = newLeft + 'px'
baseDialog.value.style.top = newTop + "px"; baseDialog.value.style.top = newTop + 'px'
baseDialog.value.style.bottom = "unset"; baseDialog.value.style.bottom = 'unset'
baseDialog.value.style.right = "unset"; baseDialog.value.style.right = 'unset'
}
} }
};
// 鼠标抬起事件处理 // 鼠标抬起事件处理
const handleMouseUp = () => { const handleMouseUp = () => {
window.removeEventListener('mousemove', handleMouseMove); window.removeEventListener('mousemove', handleMouseMove)
window.removeEventListener('mouseup', handleMouseUp); window.removeEventListener('mouseup', handleMouseUp)
}; }
// 添加事件监听 // 添加事件监听
window.addEventListener('mousemove', handleMouseMove); window.addEventListener('mousemove', handleMouseMove)
window.addEventListener('mouseup', handleMouseUp); window.addEventListener('mouseup', handleMouseUp)
};
} }
}; }
}
const openPosition = () => { const openPosition = () => {
const oMoveDiv = baseDialog.value; const oMoveDiv = baseDialog.value
if (!oMoveDiv) return; if (!oMoveDiv) return
// 获取对话框尺寸 // 获取对话框尺寸
const oMoveDivHeight = oMoveDiv.offsetHeight; const oMoveDivHeight = oMoveDiv.offsetHeight
const oMoveDivWidth = oMoveDiv.offsetWidth; const oMoveDivWidth = oMoveDiv.offsetWidth
// 获取当前位置 // 获取当前位置
const leftPx = parseFloat(window.getComputedStyle(oMoveDiv).left); const leftPx = parseFloat(window.getComputedStyle(oMoveDiv).left)
const topPx = parseFloat(window.getComputedStyle(oMoveDiv).top); const topPx = parseFloat(window.getComputedStyle(oMoveDiv).top)
// 获取视口大小 // 获取视口大小
const container = props.bodyId const container = props.bodyId ? document.getElementById(props.bodyId) : document.body
? document.getElementById(props.bodyId) const windowHeight = container.clientHeight
: document.body; const windowWidth = container.clientWidth
const windowHeight = container.clientHeight;
const windowWidth = container.clientWidth;
// 边界检查 // 边界检查
let newLeft = leftPx; let newLeft = leftPx
let newTop = topPx; let newTop = topPx
if (newLeft < 0) { if (newLeft < 0) {
newLeft = 0; newLeft = 0
} else if (newLeft + oMoveDivWidth > windowWidth) { } else if (newLeft + oMoveDivWidth > windowWidth) {
newLeft = windowWidth - oMoveDivWidth; newLeft = windowWidth - oMoveDivWidth
} }
if (newTop - 10 <= 0) { if (newTop - 10 <= 0) {
newTop = -10; newTop = -10
} else if (newTop + oMoveDivHeight > windowHeight) { } else if (newTop + oMoveDivHeight > windowHeight) {
newTop = windowHeight - oMoveDivHeight; newTop = windowHeight - oMoveDivHeight
} }
// 更新位置 // 更新位置
oMoveDiv.style.left = newLeft + "px"; oMoveDiv.style.left = newLeft + 'px'
oMoveDiv.style.top = newTop + "px"; oMoveDiv.style.top = newTop + 'px'
}; }
// 暴露公共方法 // 暴露公共方法
defineExpose({ defineExpose({
@ -256,7 +262,7 @@ defineExpose({
close, close,
moveDiv, moveDiv,
openPosition openPosition
}); })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -268,16 +274,17 @@ defineExpose({
color: #fff; color: #fff;
} }
.el-tabs__item:nth-child(2) { .el-tabs__item:nth-child(2) {
padding: 0; padding-left: 0;
} }
.el-tabs__item.is-active, .el-tabs__item:hover { .el-tabs__item.is-active,
.el-tabs__item:hover {
color: #fff; color: #fff;
} }
.el-tabs__active-bar { .el-tabs__active-bar {
background-color: rgb(0, 255, 255); background-color: rgb(0, 255, 255);
} }
.el-tabs__nav-wrap:after { .el-tabs__nav-wrap:after {
background-color: rgba(204, 204, 204, 0.2) background-color: rgba(204, 204, 204, 0.2);
} }
} }
} }

View File

@ -67,7 +67,8 @@ const submitForm = async (formEl: FormInstance | undefined) => {
const add = throttle(async () => { const add = throttle(async () => {
let parentId = getKeyOfSelectedNode(window.treeObj, 'id') let parentId = getKeyOfSelectedNode(window.treeObj, 'id')
let fnone = getSelectedNode(window.treeObj) let fnone = getSelectedNode(window.treeObj)
const res = await TreeApi.addDirectory({ const res: any = await TreeApi.addDirectory({
id: new YJ.Tools().randomString(),
sourceName: form.sourceName, sourceName: form.sourceName,
parentId parentId
}) })

View File

@ -25,7 +25,7 @@ import '../public/tree/jquery.ztree.exhide.js'
import '../public/tree/fuzzysearch.js' import '../public/tree/fuzzysearch.js'
import '../public/tree/newFuzzySearch' import '../public/tree/newFuzzySearch'
import Pagination from './components/Pagination/index.vue' import Pagination from './components/Pagination/index.vue'
process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true"; // process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";
const i18n = createI18n({ const i18n = createI18n({
legacy: false, legacy: false,
locale: 'zh-CN', locale: 'zh-CN',

View File

@ -1,8 +1,13 @@
<template> <template>
<div class="bottomMenuBox zIndex9"> <div class="bottomMenuBox zIndex9">
<div class="animate__animated bottomMenu"> <div class="animate__animated bottomMenu">
<div class="bottom_box" v-for="(item, i) of bottomMenuList" :key="i" :title="t('bottomMenu.' + item.sourceType)" <div
@click="addMarker(item)"> class="bottom_box"
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) }}
@ -15,11 +20,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' 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'
const { t } = useI18n() const { t } = useI18n()
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const i8n = ref({ const i8n = ref({
DrawRect: 'rect', DrawRect: 'rect',
@ -42,7 +47,7 @@ const bottomMenuList = ref([
sourceType: 'groundText', sourceType: 'groundText',
className: 'public', className: 'public',
fun: () => { fun: () => {
eventBus.emit("openDialog", 'groundText'); eventBus.emit('openDialog', 'addGroundText')
} }
}, },
{ {
@ -51,7 +56,8 @@ const bottomMenuList = ref([
sourceType: 'standText', sourceType: 'standText',
className: 'public', className: 'public',
fun: () => { fun: () => {
eventBus.emit("openDialog", 'standText'); eventBus.emit('openDialog', 'addStandText')
// eventBus.emit("openDialog", 'standText');
} }
}, },
{ {
@ -70,19 +76,22 @@ const bottomMenuList = ref([
let options: any = await initMapData('point', { let options: any = await initMapData('point', {
id: id, id: id,
name: name, name: name,
position: position, position: position
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
delete options.host delete options.host
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "point", sourceType: 'point',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addDirectory(params) TreeApi.addOtherSource(params)
}) })
} }
}, },
@ -104,18 +113,21 @@ const bottomMenuList = ref([
let options: any = await initMapData('line', { let options: any = await initMapData('line', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "line", sourceType: 'line',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addDirectory(params) TreeApi.addOtherSource(params)
}) })
} }
}, },
@ -135,19 +147,21 @@ const bottomMenuList = ref([
let options: any = await initMapData('curve', { let options: any = await initMapData('curve', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "curve", sourceType: 'curve',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addDirectory(params) TreeApi.addOtherSource(params)
}) })
} }
}, },
@ -158,7 +172,7 @@ const bottomMenuList = ref([
className: 'public', className: 'public',
fun: () => { fun: () => {
let Draw = new YJ.Draw.DrawPolygon(window.earth) let Draw = new YJ.Draw.DrawPolygon(window.earth)
Draw.start((a, positions) => { Draw.start(async (a, positions) => {
if (!positions || positions.length < 3) { if (!positions || positions.length < 3) {
ElMessage({ ElMessage({
message: '至少需要绘制三个坐标!', message: '至少需要绘制三个坐标!',
@ -166,11 +180,30 @@ const bottomMenuList = ref([
}) })
return return
} }
let PolygonObject = new YJ.Obj.PolygonObject(window.earth, { id: new YJ.Tools().randomString(), positions: positions }) let id = new YJ.Tools().randomString()
PolygonObject.onClick = (a, b, c) => { // let id = 'aaa'
console.log(a, b, c) let name = '面标注'
let options: any = await initMapData('panel', {
id: id,
name: name,
positions: positions
})
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: 'panel',
parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0,
params: options
} }
eventBus.emit("openDialog", 'panel', PolygonObject.options.id); console.log(params)
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params)
}) })
} }
}, },
@ -184,26 +217,175 @@ const bottomMenuList = ref([
sourceName: '矩形', sourceName: '矩形',
key: 'DrawRect', key: 'DrawRect',
sourceType: 'rectangle', sourceType: 'rectangle',
className: 'public' className: 'public',
fun: () => {
let Draw = new YJ.Draw.DrawRect(window.earth)
Draw.start(async (a, positions) => {
if (!positions || positions.length < 3) {
ElMessage({
message: '至少需要绘制三个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
// let id = 'aaa'
let name = '矩形'
let options: any = await initMapData('panel', {
id: id,
name: name,
positions: positions
})
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: 'rectangle',
parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0,
params: options
}
console.log(params)
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params)
})
}
}, },
{ {
sourceName: '集结地', sourceName: '集结地',
key: 'DrawAssemble', key: 'DrawAssemble',
sourceType: 'rendezvous', sourceType: 'rendezvous',
className: 'public' className: 'public',
fun: () => {
let Draw = new YJ.Draw.DrawAssemble(window.earth)
Draw.start(async (a, positions) => {
if (!positions || positions.length < 3) {
ElMessage({
message: '至少需要绘制三个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
// let id = 'aaa'
let name = '集结地'
let options: any = await initMapData('rendezvous', {
id: id,
name: name,
positions: positions
})
delete options.label.ground
delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: 'rendezvous',
parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0,
params: options
}
console.log(params)
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params)
})
}
}, },
{ {
sourceName: '箭头', sourceName: '箭头',
key: 'DrawAttackArrow', key: 'DrawAttackArrow',
sourceType: 'attackArrow', sourceType: 'attackArrow',
className: 'public' className: 'public',
fun: () => {
let Draw = new YJ.Draw.DrawAttackArrow(window.earth)
Draw.start(async (a, positions) => {
if (!positions || positions.length < 3) {
ElMessage({
message: '至少需要绘制三个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
// let id = 'aaa'
let name = '箭头'
let options: any = await initMapData('attackArrow', {
id: id,
name: name,
positions: positions
})
delete options.label.ground
delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: 'attackArrow',
parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0,
params: options
}
console.log(params)
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params)
})
}
}, },
{ {
sourceName: '钳形箭头', sourceName: '钳形箭头',
key: 'DrawPincerArrow', key: 'DrawPincerArrow',
sourceType: 'pincerArrow', sourceType: 'pincerArrow',
className: 'public' className: 'public',
fun: () => {
let Draw = new YJ.Draw.DrawPincerArrow(window.earth)
Draw.start(async (a, positions) => {
if (!positions || positions.length < 5) {
ElMessage({
message: '至少需要绘制五个坐标!',
type: 'warning'
})
return
}
let id = new YJ.Tools().randomString()
// let id = 'aaa'
let name = '双箭头'
let options: any = await initMapData('pincerArrow', {
id: id,
name: name,
positions: positions
})
delete options.label.ground
delete options.label.position
let selectedNodes = window.treeObj.getSelectedNodes()
let params = {
id: id,
sourceName: name,
sourceType: 'pincerArrow',
parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0,
params: options
}
// eventBus.emit("openDialog", 'panel');
TreeApi.addOtherSource(params)
})
}
} }
// { // {
// sourceName: "锁定", // sourceName: "锁定",
@ -303,7 +485,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

@ -1,7 +1,7 @@
<template> <template>
<Dialog ref="baseDialog" title="贴地文字" left="180px" top="100px"> <Dialog ref="baseDialog" title="贴地文字" left="calc(50% - 160px)" top="calc(50% - 120px)">
<template #content> <template #content>
<textarea style="height: 76px; width: 270px;" v-model="text"></textarea> <textarea style="height: 76px; width: 270px" v-model="text"></textarea>
</template> </template>
<template #footer> <template #footer>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
@ -10,18 +10,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; 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'
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const text = ref("") const text = ref('')
eventBus.on("openStandTextAdd", () => { eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open() baseDialog.value?.open()
}); })
const open = () => { const open = () => {
baseDialog.value?.open() baseDialog.value?.open()
} }
@ -31,25 +31,29 @@ const confirm = () => {
text.value = '' text.value = ''
let Draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 }) let Draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 })
Draw.start(async (a, positions) => { Draw.start(async (a, positions) => {
if(!positions || positions.length < 2) { if (!positions || positions.length < 2) {
return return
} }
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, name: name,
positions: positions, positions: positions
}) })
delete options.host
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "groundText", sourceType: 'groundText',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addDirectory(params) TreeApi.addOtherSource(params)
}) })
} }
defineExpose({ defineExpose({

View File

@ -1,7 +1,7 @@
<template> <template>
<Dialog ref="baseDialog" title="立体文字" left="180px" top="100px"> <Dialog ref="baseDialog" title="立体文字" left="calc(50% - 160px)" top="calc(50% - 120px)">
<template #content> <template #content>
<textarea style="height: 76px; width: 270px;" v-model="text"></textarea> <textarea style="height: 76px; width: 270px" v-model="text"></textarea>
</template> </template>
<template #footer> <template #footer>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
@ -10,18 +10,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; 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'
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const text = ref("") const text = ref('')
eventBus.on("openStandTextAdd", () => { eventBus.on('openStandTextAdd', () => {
baseDialog.value?.open() baseDialog.value?.open()
}); })
const open = () => { const open = () => {
baseDialog.value?.open() baseDialog.value?.open()
} }
@ -38,18 +38,22 @@ const confirm = () => {
let options: any = await initMapData('standText', { let options: any = await initMapData('standText', {
id: id, id: id,
name: name, name: name,
positions: positions, positions: positions
}) })
delete options.host
let selectedNodes = window.treeObj.getSelectedNodes() let selectedNodes = window.treeObj.getSelectedNodes()
let params = { let params = {
"id": id, id: id,
"sourceName": name, sourceName: name,
"sourceType": "standText", sourceType: 'standText',
"parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined, parentId:
selectedNodes && selectedNodes[selectedNodes.length - 1]
? selectedNodes[selectedNodes.length - 1].id
: undefined,
// "treeIndex": 0, // "treeIndex": 0,
"params": options params: options
} }
TreeApi.addDirectory(params) TreeApi.addOtherSource(params)
}) })
} }
defineExpose({ defineExpose({

View File

@ -0,0 +1,368 @@
<template>
<Dialog ref="baseDialog" :title="title + '属性'" left="180px" top="100px" className="attackArrow"
: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 class="row">
<div class="col">
<span class="label">动画时长</span>
<div class="input-number input-number-unit-3">
<input class="input blur" type="number" title="" min="500" max="9999999" v-model="entityOptions.spreadTime">
<span class="unit">ms</span>
<span class="arrow"></span>
</div>
</div>
<div class="col" style="flex: 0 0 60%;">
<div class="row">
<div class="col">
<span class="label">动画</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.spreadState">
</div>
<div class="col">
<span class="label">动画重复</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.loop">
</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" 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" 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" 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="entityOptions.height" min="-9999999" max="999999999"
v-if="activeTd.index == i && 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 positions = ref([])
const heightMode = ref(0)
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const open = async (id: any, type: any) => {
if(type && type === 'pincerArrow') {
title.value = '双箭头'
}
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
heightMode.value = entityOptions.value.heightMode
area.value = entityOptions.value.areaByMeter
positions.value = structuredClone(that.options.positions)
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
}
}
let spreadState = entityOptions.value.spreadState
heightModeChange(heightMode.value)
setTimeout(() => {
entityOptions.value.spreadState = spreadState
}, 50);
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 = () => {
entityOptions.value.spreadState = false
that.openPositionEditing(() => {
entityOptions.value.options.positions = structuredClone(that.options.positions)
})
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.closeNodeEdit()
entityOptions.value.reset()
eventBus.emit("destroyComponent")
}
const nodeEdit = () => {
entityOptions.value.spreadState = false
that.nodeEdit((e, positions, areaByMeter) => {
entityOptions.value.options.positions = structuredClone(positions)
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
let params = structuredClone(that.options)
baseDialog.value?.close()
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

@ -2,9 +2,19 @@
<div class="attribute"> <div class="attribute">
<div class="row"> <div class="row">
<div class="col attribute-select-box"> <div class="col attribute-select-box">
<span class="label" style="line-height: 32px;">内容类型</span> <span class="label" style="line-height: 32px">内容类型</span>
<el-select style="width: 175px" v-model="attributeType" @change="attributeChange" placeholder="请选择"> <el-select
<el-option v-for="item in attributeSelect" :key="item.key" :label="item.name" :value="item.key"> style="width: 175px"
v-model="attributeType"
@change="attributeChange"
placeholder="请选择"
>
<el-option
v-for="item in attributeSelect"
:key="item.key"
:label="item.name"
:value="item.key"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
@ -20,8 +30,8 @@
<div class="row attribute-content attribute-content-link" v-show="attributeType === 'link'"> <div class="row attribute-content attribute-content-link" v-show="attributeType === 'link'">
<div class="col"> <div class="col">
<span class="label">添加链接</span> <span class="label">添加链接</span>
<div style="flex: 1;position: relative;"> <div style="flex: 1; position: relative">
<input class="input link_add" type="text" v-model="addlinkInput"> <input class="input link_add" type="text" v-model="addlinkInput" />
<i class="link_add_btn" @click="_addLink"></i> <i class="link_add_btn" @click="_addLink"></i>
</div> </div>
</div> </div>
@ -38,7 +48,7 @@
<div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0"> <div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0">
<div class="tr" v-for="(item, index) in attribute.link.content"> <div class="tr" v-for="(item, index) in attribute.link.content">
<div class="td" v-if="linkEditActive.index === index"> <div class="td" v-if="linkEditActive.index === index">
<input class="input" type="text" v-model="linkEditActive.name"> <input class="input" type="text" v-model="linkEditActive.name" />
</div> </div>
<div class="td" v-else>{{ item.name }}</div> <div class="td" v-else>{{ item.name }}</div>
<div class="td" v-if="linkEditActive.index === index"> <div class="td" v-if="linkEditActive.index === index">
@ -53,7 +63,6 @@
<button @click="linkEdit(index, item)">编辑</button> <button @click="linkEdit(index, item)">编辑</button>
<button @click="linkDelete(index)">删除</button> <button @click="linkDelete(index)">删除</button>
</div> </div>
</div> </div>
</div> </div>
<div class="table-empty" v-else> <div class="table-empty" v-else>
@ -66,7 +75,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">编辑内容</span> <span class="label">编辑内容</span>
<input class="input" type="text" @model="cameraName" style="width: 100px;"> <input class="input" type="text" @model="cameraName" style="width: 100px" />
<button class="select btn" @click="cameraSelect">搜索</button> <button class="select btn" @click="cameraSelect">搜索</button>
</div> </div>
</div> </div>
@ -76,17 +85,17 @@
<div class="tr"> <div class="tr">
<div class="th">操作</div> <div class="th">操作</div>
<div class="th">设备名称</div> <div class="th">设备名称</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">设备类型</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">设备类型</div>
<div class="th" style="width: 126px; flex: 0 126px;min-width: 126px;">设备IP</div> <div class="th" style="width: 126px; flex: 0 126px; min-width: 126px">设备IP</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">设备端口</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">设备端口</div>
<div class="th" style="width: 80px; flex: 0 80px;min-width: 80px;">用户名</div> <div class="th" style="width: 80px; flex: 0 80px; min-width: 80px">用户名</div>
<div class="th">密码</div> <div class="th">密码</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td"> <div class="td">
<input type="checkbox" value="2"> <input type="checkbox" value="2" />
<span>绑定</span> <span>绑定</span>
</div> </div>
<div class="td">设备名称</div> <div class="td">设备名称</div>
@ -119,19 +128,19 @@
<div class="table isc-table"> <div class="table isc-table">
<div class="table-head"> <div class="table-head">
<div class="tr"> <div class="tr">
<div class="th" style="width: 74px; flex: 0 74px;min-width: 74px;">操作</div> <div class="th" style="width: 74px; flex: 0 74px; min-width: 74px">操作</div>
<div class="th">设备名称</div> <div class="th">设备名称</div>
<div class="th" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div> <div class="th" style="width: 180px; flex: 0 180px; min-width: 180px">设备状态</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td"> <div class="td">
<input type="checkbox" value="2"> <input type="checkbox" value="2" />
<span>绑定</span> <span>绑定</span>
</div> </div>
<div class="td">设备名称</div> <div class="td">设备名称</div>
<div class="td" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div> <div class="td" style="width: 180px; flex: 0 180px; min-width: 180px">设备状态</div>
</div> </div>
</div> </div>
<div class="table-empty"> <div class="table-empty">
@ -147,8 +156,8 @@
<div class="row attribute-content attribute-content-vr" v-show="attributeType === 'vr'"> <div class="row attribute-content attribute-content-vr" v-show="attributeType === 'vr'">
<div class="col"> <div class="col">
<span class="label">添加链接</span> <span class="label">添加链接</span>
<div style="flex: 1;position: relative;"> <div style="flex: 1; position: relative">
<input class="input vr_add" type="text"> <input class="input vr_add" type="text" />
<i class="vr_add_btn" @click="_addRr"></i> <i class="vr_add_btn" @click="_addRr"></i>
</div> </div>
</div> </div>
@ -162,8 +171,7 @@
<div class="th">操作</div> <div class="th">操作</div>
</div> </div>
</div> </div>
<div class="table-body"> <div class="table-body"></div>
</div>
<div class="table-empty"> <div class="table-empty">
<div class="empty-img"></div> <div class="empty-img"></div>
<p>暂无数据</p> <p>暂无数据</p>
@ -175,22 +183,26 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">编辑内容</span> <span class="label">编辑内容</span>
<input class="input goods-select-input" type="text" style="width: 180px;margin-right: 10px;"> <input
class="input goods-select-input"
type="text"
style="width: 180px; margin-right: 10px"
/>
<button class="select btn" @click="goodsFilter">搜索</button> <button class="select btn" @click="goodsFilter">搜索</button>
</div> </div>
</div> </div>
<div class="table goods-table"> <div class="table goods-table">
<div class="table-head"> <div class="table-head">
<div class="tr"> <div class="tr">
<div class="th" style="width: 60px; flex: 0 60px;min-width: 60px;">序号</div> <div class="th" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
<div class="th" style="flex: 0 0 280px;">名称</div> <div class="th" style="flex: 0 0 280px">名称</div>
<div class="th">数量</div> <div class="th">数量</div>
</div> </div>
</div> </div>
<div class="table-body" style="display:none;"> <div class="table-body" style="display: none">
<div class="tr"> <div class="tr">
<div class="td" style="width: 60px; flex: 0 60px;min-width: 60px;">序号</div> <div class="td" style="width: 60px; flex: 0 60px; min-width: 60px">序号</div>
<div class="td" style="flex: 0 0 280px;">名称</div> <div class="td" style="flex: 0 0 280px">名称</div>
<div class="td">数量</div> <div class="td">数量</div>
</div> </div>
</div> </div>
@ -205,11 +217,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const attributeType = ref('richText') const attributeType = ref('richText')
const props = defineProps({ const props = defineProps({
@ -232,7 +244,7 @@ const attributeSelect = ref([
name: '链接', name: '链接',
value: '链接', value: '链接',
key: 'link' key: 'link'
}, }
// { // {
// name: 'IP摄像头', // name: 'IP摄像头',
// value: 'IP摄像头', // value: 'IP摄像头',
@ -260,10 +272,9 @@ const attributeSelect = ref([
// }, // },
]) ])
const cameraName = ref('') const cameraName = ref('')
const addlinkInput = ref('') const addlinkInput = ref('')
const linkEditActive = ref({}) const linkEditActive: any = ref({})
const openRichTextEditor = () => { const openRichTextEditor = () => {
eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => { eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => {
@ -278,16 +289,15 @@ const _addLink = () => {
} }
attribute.value.link.content.push(link) attribute.value.link.content.push(link)
addlinkInput.value = '' addlinkInput.value = ''
} } else {
else { document.getElementById('fileInputlink')?.click()
document.getElementById('fileInputlink')?.click();
eventBus.emit('defineClickAddLinkCb', (list) => { eventBus.emit('defineClickAddLinkCb', (list) => {
list.forEach((item) => { list.forEach((item) => {
attribute.value.link.content.push({ attribute.value.link.content.push({
name: "链接", name: '链接',
url: item.previewUrl, url: item.previewUrl
}); })
}); })
}) })
} }
} }
@ -309,12 +319,10 @@ const linkConfirmEdit = (index) => {
const linkCancelEdit = () => { const linkCancelEdit = () => {
linkEditActive.value = {} linkEditActive.value = {}
} }
const cameraSelect = () => { } const cameraSelect = () => {}
const _addRr = () => { } const _addRr = () => {}
const goodsFilter = () => { } const goodsFilter = () => {}
const attributeChange = () => { } const attributeChange = () => {}
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -1,78 +1,132 @@
<template> <template>
<Dialog ref="baseDialog" title="点标注" left="180px" top="100px" :className="'billboard-object'" <Dialog
:closeCallback="closeCallback"> ref="baseDialog"
title="点标注"
left="180px"
top="100px"
:className="'billboard-object'"
:closeCallback="closeCallback"
>
<template #content> <template #content>
<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"> <div class="col">
<span class="label" style="flex: unset;">名称</span> <span class="label" style="flex: unset">名称</span>
<input class="input" type="text" v-model="entityOptions.name" @change="changeName"> <input class="input" type="text" v-model="entityOptions.name" @change="changeName" />
</div>
<div class="col">
</div> </div>
<div class="col"></div>
</div> </div>
</div> </div>
<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 style="width: 46%;"> <div style="width: 46%">
<div class="row"> <div class="row">
<p class="lable-left-line">WGS84坐标</p> <p class="lable-left-line">WGS84坐标</p>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">经度</span> <span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" v-model="entityOptions.lng" <input
@change="changLng"> class="input"
type="number"
title=""
min="-180"
max="180"
v-model="entityOptions.lng"
@change="changLng"
/>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">纬度</span> <span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat" <input
@change="changLat"> class="input"
type="number"
title=""
min="-90"
max="90"
v-model="entityOptions.lat"
@change="changLat"
/>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">海拔高度</span> <span class="label">海拔高度</span>
<div class="input-number input-number-unit-1 alt-box" <div
:class="{ 'disabled': heightMode == 2 || heightMode === 3 }"> class="input-number input-number-unit-1 alt-box"
<input class="input" type="number" title="" min="-9999999" max="999999999" v-model="entityOptions.alt" :class="{ disabled: heightMode == 2 || heightMode === 3 }"
@change="changAlt"> >
<input
class="input"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="entityOptions.alt"
@change="changAlt"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div style="width: 50%;"> <div style="width: 50%">
<div class="row coordinate-select-box"> <div class="row coordinate-select-box">
<div class="lable-left-line">转换坐标选择 <div class="lable-left-line">
<el-select class="input input-select coordinate-select" style="width: 155px;margin-left: 20px" 转换坐标选择
v-model="coordinate" @change="coordinateChange" placeholder="请选择"> <el-select
<el-option v-for="item in epsg_map" :key="item.epsg" :label="item.name" :value="item.epsg"> class="input input-select coordinate-select"
style="width: 155px; margin-left: 20px"
v-model="coordinate"
@change="coordinateChange"
placeholder="请选择"
>
<el-option
v-for="item in epsg_map"
:key="item.epsg"
:label="item.name"
:value="item.epsg"
>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">X轴:</span> <span class="label">X轴:</span>
<input style="border: none;background: none;" class="input convert-x" readonly="readonly" v-model="x"> <input
style="border: none; background: none"
class="input convert-x"
readonly
v-model="x"
/>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 5px;"> <div class="row" style="margin-bottom: 5px">
<div class="col"> <div class="col">
<span class="label">Y轴:</span> <span class="label">Y轴:</span>
<input style="border: none;background: none;" class="input convert-y" readonly="readonly" v-model="y"> <input
style="border: none; background: none"
class="input convert-y"
readonly
v-model="y"
/>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">Z轴:</span> <span class="label">Z轴:</span>
<input style="border: none;background: none;" class="input convert-z" readonly="readonly" v-model="z"> <input
style="border: none; background: none"
class="input convert-z"
readonly
v-model="z"
/>
</div> </div>
</div> </div>
</div> </div>
@ -81,14 +135,21 @@
<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" 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" type="checkbox" v-model="entityOptions.scaleByDistance"> <input class="btn-switch" type="checkbox" v-model="entityOptions.scaleByDistance" />
</div> </div>
<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 class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.near"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.near"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -96,7 +157,14 @@
<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 class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.far"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.far"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -110,18 +178,35 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<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 class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> 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-option>
</el-select> </el-select>
</div> </div>
<div class="col height-box" v-show="heightMode == 0 || heightMode == 1"> <div class="col height-box" v-show="heightMode == 0 || heightMode == 1">
<span class="label" style="flex: 0 0 56px;">高度</span> <span class="label" style="flex: 0 0 56px">高度</span>
<div class="input-number input-number-unit-1"> <div class="input-number input-number-unit-1">
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height" <input
@change="changHeight"> class="input height"
type="number"
title=""
min="-9999999"
max="999999999"
v-model="height"
@change="changHeight"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -129,92 +214,134 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(1)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format1"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">小数格式</span> @click="formatChange(1)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format1" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>小数格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(2)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format2"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分格式</span> @click="formatChange(2)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format2" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>度分格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col">
<div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;" <div
@click="formatChange(3)"> class="YJ-custom-checkbox-box"
<input type="checkbox" class="YJ-custom-checkbox" v-model="format3"> style="display: flex; align-items: center; cursor: pointer"
<span style="margin-left: 10px; margin-bottom: 1px;user-select: none;">度分秒格式</span> @click="formatChange(3)"
>
<input type="checkbox" class="YJ-custom-checkbox" v-model="format3" />
<span style="margin-left: 10px; margin-bottom: 1px; user-select: none"
>度分秒格式</span
>
</div> </div>
</div> </div>
<div class="col"> <div class="col"></div>
</div>
</div> </div>
<div class="row"> <div class="row">
<div style="flex: 1;"> <div style="flex: 1">
<div class="proj-input-box" v-show="format1"> <div class="proj-input-box" v-show="format1">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng" readonly="readonly" :value="entityOptions.lng"> <input class="input lng" readonly :value="entityOptions.lng" />
</div>
<div class="col">
</div> </div>
<div class="col"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat" readonly="readonly" :value="entityOptions.lat"> <input class="input lat" readonly :value="entityOptions.lat" />
</div> </div>
<div class="col"> <div class="col"></div>
</div> </div>
</div> </div>
</div> <div class="proj-input-box" style="width: 56%" v-show="format2">
<div class="proj-input-box" style="width: 56%;" v-show="format2">
<div class="row"> <div class="row">
<div class="col" style="flex-direction: column;"> <div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng-dm-d" style="flex: 1;" readonly="readonly" :value="lngDmD"> <input class="input lng-dm-d" style="flex: 1" readonly :value="lngDmD" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input class="input lng-dm-m" style="flex: 1;" readonly="readonly" :value="lngDmM"> <input class="input lng-dm-m" style="flex: 1" readonly :value="lngDmM" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span> <span class="top-line"></span>
</div> </div>
<div class="row"> <div class="row">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat-dm-d" style="flex: 1;" readonly="readonly" :value="latDmD"> <input class="input lat-dm-d" style="flex: 1" readonly :value="latDmD" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input class="input lat-dm-m" style="flex: 1;" readonly="readonly" :value="latDmM"> <input class="input lat-dm-m" style="flex: 1" readonly :value="latDmM" />
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> <span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span> <span class="bottom-line"></span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="proj-input-box" style="width: 70%;" v-show="format3"> <div class="proj-input-box" style="width: 70%" v-show="format3">
<div class="row"> <div class="row">
<div class="col" style="flex-direction: column;"> <div class="col" style="flex-direction: column">
<div class="row" style="margin-bottom: 15px;"> <div class="row" style="margin-bottom: 15px">
<span style="flex: 0 0 40px;">经度</span> <span style="flex: 0 0 40px">经度</span>
<input class="input lng-dms-d" style="flex: 1;" readonly="readonly" :value="lngDmsD"> <input
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> class="input lng-dms-d"
<input class="input lng-dms-m" style="flex: 1;" readonly="readonly" :value="lngDmsM"> style="flex: 1"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> readonly
<input class="input lng-dms-s" style="flex: 1;" readonly="readonly" :value="lngDmsS"> :value="lngDmsD"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> />
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dms-m"
style="flex: 1"
readonly
:value="lngDmsM"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lng-dms-s"
style="flex: 1"
readonly
:value="lngDmsS"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="top-line"></span> <span class="top-line"></span>
</div> </div>
<div class="row"> <div class="row">
<span style="flex: 0 0 40px;">纬度</span> <span style="flex: 0 0 40px">纬度</span>
<input class="input lat-dms-d" style="flex: 1;" readonly="readonly" :value="latDmsD"> <input
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> class="input lat-dms-d"
<input class="input lat-dms-m" style="flex: 1;" readonly="readonly" :value="latDmsM"> style="flex: 1"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> readonly
<input class="input lat-dms-s" style="flex: 1;" readonly="readonly" :value="latDmsS"> :value="latDmsD"
<span class="label" style="flex: 0 0 14px;margin: 0 10px;"></span> />
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dms-m"
style="flex: 1"
readonly
:value="latDmsM"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<input
class="input lat-dms-s"
style="flex: 1"
readonly
:value="latDmsS"
/>
<span class="label" style="flex: 0 0 14px; margin: 0 10px"></span>
<span class="bottom-line"></span> <span class="bottom-line"></span>
</div> </div>
</div> </div>
@ -226,28 +353,38 @@
<el-tab-pane label="标注风格" name="3"> <el-tab-pane label="标注风格" name="3">
<div> <div>
<h4>图标设置</h4> <h4>图标设置</h4>
<div class="row" style="margin-bottom: 10px;"> <div class="row" style="margin-bottom: 10px">
<div class="col" style="flex: 0 0 80px;"> <div class="col" style="flex: 0 0 80px">
<span class="label" style="flex: none;">显隐</span> <span class="label" style="flex: none">显隐</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.billboardShow"> <input
class="btn-switch"
type="checkbox"
v-model="entityOptions.billboardShow"
/>
</div> </div>
<div class="col" style="flex: 0 0 90px;"> <div class="col" style="flex: 0 0 90px">
<span class="label" style="flex: none;">图标</span> <span class="label" style="flex: none">图标</span>
<div class="image-box" @click="clickChangeImage"> <div class="image-box" @click="clickChangeImage">
<img class="image" :src="entityOptions.billboardImage" alt=""> <img class="image" :src="entityOptions.billboardImage" alt="" />
</div> </div>
</div> </div>
<div class="col" style="flex: 0 0 90px;"> <div class="col" style="flex: 0 0 90px">
<span class="label" style="flex: none;">默认图标</span> <span class="label" style="flex: none">默认图标</span>
<div class="image-box" @click="clickChangeDefaultImage"> <div class="image-box" @click="clickChangeDefaultImage">
<img class="image" :src="entityOptions.billboardDefaultImage" alt=""> <img class="image" :src="entityOptions.billboardDefaultImage" alt="" />
</div> </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 class="input" type="number" title="" min="0.1" max="99" <input
v-model="entityOptions.billboardScale"> class="input"
type="number"
title=""
min="0.1"
max="99"
v-model="entityOptions.billboardScale"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -257,22 +394,38 @@
<div> <div>
<h4>文字设置</h4> <h4>文字设置</h4>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 80px;"> <div class="col" style="flex: 0 0 80px">
<span class="label" style="flex: none;">显隐</span> <span class="label" style="flex: none">显隐</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow" />
</div> </div>
<div class="col font-select-box"> <div class="col font-select-box">
<span class="label" style="flex: none;">字体选择</span> <span class="label" style="flex: none">字体选择</span>
<el-select class="input input-select font-select" style="width: 100px;" v-model="entityOptions.labelFontFamily"> <el-select
<el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key"> class="input input-select font-select"
style="width: 100px"
v-model="entityOptions.labelFontFamily"
>
<el-option
v-for="item in fontList"
: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">文字大小</span> <span class="label">文字大小</span>
<div class="input-number input-number-unit-2"> <div class="input-number input-number-unit-2">
<input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize" <input
style="width: 70px;"> class="input"
type="number"
title=""
min="1"
max="99"
v-model="entityOptions.labelFontSize"
style="width: 70px"
/>
<span class="unit">px</span> <span class="unit">px</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -289,11 +442,13 @@
</div> </div>
</template> </template>
<template #footer> <template #footer>
<div style="position: absolute; left: 24px; display: flex;"> <div style="position: absolute; left: 24px; display: flex">
<button @click="updateHeight"><svg class="icon-updateheigh"> <button @click="updateHeight">
<use xlink:href="#yj-icon-updateheight"></use> <svg class="icon-updateheigh">
</svg>更新高程</button> <use xlink:href="#yj-icon-updateheight"></use></svg
<button style="margin-left: 10px;" @click="translate">平移</button> >更新高程
</button>
<button style="margin-left: 10px" @click="translate">平移</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -302,8 +457,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; 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 attribute from './attribute.vue' import attribute from './attribute.vue'
@ -312,15 +467,17 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const epsg_map = ref([{ const epsg_map = ref([
"name": "WGS 84 / UTM zone 3N", {
"epsg": "EPSG:32603", name: 'WGS 84 / UTM zone 3N',
"def": "+proj=utm +zone=3 +datum=WGS84 +units=m +no_defs" epsg: 'EPSG:32603',
}]) def: '+proj=utm +zone=3 +datum=WGS84 +units=m +no_defs'
let array = [] }
])
let array: any[] = []
for (const [key, value] of window.earth.proj.epsg_map) { for (const [key, value] of window.earth.proj.epsg_map) {
let item = structuredClone(value) let item = structuredClone(value)
item.name = item.name + `(${item.epsg}})` item.name = item.name + `(${item.epsg}})`
@ -367,10 +524,10 @@ const heightModeData = ref([
} }
]) ])
const activeName = ref('1') const activeName = ref('1')
const entityOptions = ref({}); const entityOptions: any = ref({})
const x = ref(); const x = ref()
const y = ref(); const y = ref()
const z = ref(); const z = ref()
const coordinate = ref('EPSG:4326') const coordinate = ref('EPSG:4326')
const heightMode = ref(0) const heightMode = ref(0)
const labelColorRef = ref(null) const labelColorRef = ref(null)
@ -390,14 +547,14 @@ const open = async (id) => {
baseDialog.value?.open() baseDialog.value?.open()
await nextTick() await nextTick()
let labelColorPicker = new YJColorPicker({ let labelColorPicker = new window.YJColorPicker({
el: labelColorRef.value, el: labelColorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.labelColor, defaultColor: entityOptions.value.labelColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.labelColor = color entityOptions.value.labelColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -410,10 +567,9 @@ const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions) entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false that.positionEditing = false
that.reset() that.reset()
eventBus.emit("destroyComponent") eventBus?.emit('destroyComponent')
} }
const changeName = (e) => { const changeName = (e) => {
entityOptions.value.labelText = e.target.value entityOptions.value.labelText = e.target.value
} }
@ -435,7 +591,6 @@ const coordinateChange = () => {
z.value = position[0].z z.value = position[0].z
} }
const heightModeChange = (val) => { const heightModeChange = (val) => {
switch (val) { switch (val) {
case 0: case 0:
@ -445,15 +600,9 @@ const heightModeChange = (val) => {
case 1: case 1:
case '1': case '1':
if (window.earth.viewer.scene.terrainProvider.availability) { if (window.earth.viewer.scene.terrainProvider.availability) {
Cesium.sampleTerrainMostDetailed( window.Cesium.sampleTerrainMostDetailed(window.earth.viewer.scene.terrainProvider, [
window.earth.viewer.scene.terrainProvider, window.Cesium.Cartographic.fromDegrees(entityOptions.value.lng, entityOptions.value.lat)
[ ]).then((position) => {
Cesium.Cartographic.fromDegrees(
entityOptions.value.lng,
entityOptions.value.lat
)
]
).then(position => {
height.value = entityOptions.value.alt - Number(position[0].height.toFixed(2)) height.value = entityOptions.value.alt - Number(position[0].height.toFixed(2))
}) })
} else { } else {
@ -465,13 +614,15 @@ const heightModeChange = (val) => {
break break
case 3: case 3:
case '3': case '3':
let objectsToExclude = [] let objectsToExclude: any[] = []
for (let [key, value] of window.earth.entityMap) { for (let [key, value] of window.earth.entityMap) {
if (value.type === 'RadarScanStereoscopic' && value.entity) { if (value.type === 'RadarScanStereoscopic' && value.entity) {
objectsToExclude.push(value.entity) objectsToExclude.push((value as any).entity)
} }
} }
entityOptions.value.getClampToHeight(entityOptions.value.options.position, objectsToExclude).then(h => { entityOptions.value
.getClampToHeight(entityOptions.value.options.position, objectsToExclude)
.then((h) => {
height.value = Number(h.toFixed(2)) height.value = Number(h.toFixed(2))
entityOptions.value.alt = Number(h.toFixed(2)) entityOptions.value.alt = Number(h.toFixed(2))
}) })
@ -496,24 +647,14 @@ const changAlt = () => {
const changHeight = () => { const changHeight = () => {
switch (heightMode.value) { switch (heightMode.value) {
case 0: case 0:
entityOptions.value.alt = Number( entityOptions.value.alt = Number(Number(height.value).toFixed(2))
Number(height.value).toFixed(2)
)
break break
case 1: case 1:
if (window.earth.viewer.scene.terrainProvider.availability) { if (window.earth.viewer.scene.terrainProvider.availability) {
Cesium.sampleTerrainMostDetailed( window.Cesium.sampleTerrainMostDetailed(window.earth.viewer.scene.terrainProvider, [
window.earth.viewer.scene.terrainProvider, window.Cesium.Cartographic.fromDegrees(entityOptions.value.lng, entityOptions.value.lat)
[ ]).then((position) => {
Cesium.Cartographic.fromDegrees( entityOptions.value.alt = Number(height.value) + Number(position[0].height.toFixed(2))
entityOptions.value.lng,
entityOptions.value.lat
)
]
).then(position => {
entityOptions.value.alt =
Number(height.value) +
Number(position[0].height.toFixed(2))
}) })
} else { } else {
entityOptions.value.alt = Number(height.value) entityOptions.value.alt = Number(height.value)
@ -524,7 +665,7 @@ const changHeight = () => {
coordinateChange() coordinateChange()
} }
const handleClick = () => { } const handleClick = () => {}
const formatChange = (val) => { const formatChange = (val) => {
switch (val) { switch (val) {
@ -600,7 +741,6 @@ const translate = () => {
that.openPositionEditing(() => { that.openPositionEditing(() => {
changAlt() changAlt()
}) })
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -608,33 +748,28 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"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.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
} }
const clickChangeImage = () => { const clickChangeImage = () => {
eventBus.emit("openImageSelect") eventBus?.emit('openImageSelect')
} }
const clickChangeDefaultImage = () => { const clickChangeDefaultImage = () => {
eventBus.emit("openImageSelect") eventBus?.emit('openImageSelect')
} }
const fontChange = (val) => { const fontChange = (val) => {
entityOptions.value.labelFontFamily = val entityOptions.value.labelFontFamily = val
} }
defineExpose({ defineExpose({
open open
}) })

View File

@ -1,14 +1,21 @@
<template> <template>
<Dialog ref="baseDialog" title="曲线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback"> <Dialog
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">
<div class="row" style="align-items: flex-start;"> <div class="row" style="align-items: flex-start">
<div class="col"> <div class="col">
<span class="label">名称</span> <span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name"> <input class="input" maxlength="40" type="text" v-model="entityOptions.name" />
</div> </div>
<div class="col" style="flex: 0 0 56%;"> <div class="col" style="flex: 0 0 56%">
<div> <div>
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col input-select-unit-box">
@ -17,7 +24,7 @@
<el-option label="投影长度" value="1"></el-option> <el-option label="投影长度" value="1"></el-option>
<el-option label="地表长度" value="2"></el-option> <el-option label="地表长度" value="2"></el-option>
</el-select> </el-select>
<input v-model="length" class="input-text" readonly="readonly"> <input v-model="length" class="input-text" readonly />
<el-select v-model="lengthUnit"> <el-select v-model="lengthUnit">
<el-option label="米" value="m"></el-option> <el-option label="米" value="m"></el-option>
<el-option label="千米" value="km"></el-option> <el-option label="千米" value="km"></el-option>
@ -37,22 +44,48 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<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 class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> 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-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box" :class="{ 'disabled': heightMode == 2 }"> <div
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height"> 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="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm" <button
:disabled="heightMode == 2">应用</button> class="confirm height-confirm"
style="margin-left: 5px"
@click="heightConfirm"
:disabled="heightMode == 2"
>
应用
</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -69,20 +102,40 @@
<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 class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number" <input
v-model="item.lng" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lng'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lng).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lng', 8)"
type="number"
v-model="item.lng"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<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 class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number" <input
v-model="item.lat" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lat'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lat).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lat', 8)"
type="number"
v-model="item.lat"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<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 class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number" <input
v-model="item.alt" min="-9999999" max="999999999" class="input"
v-if="activeTd.index == i && activeTd.name == 'alt'"> @blur="inputBlurCallBack($event, i, 'alt', 2)"
<span style="pointer-events: none;" v-else>{{ (item.alt).toFixed(2) }}</span> type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
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> </div>
@ -95,19 +148,35 @@
<span class="label">线条颜色</span> <span class="label">线条颜色</span>
<div class="color" ref="colorRef"></div> <div class="color" ref="colorRef"></div>
</div> </div>
<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 class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth"> <input
class="input"
type="number"
title=""
min="1"
max="999"
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 class="input input-select input-select-line-type" style="margin-left: 20px" <el-select
v-model="entityOptions.lineType" @change="lineTypechange"> class="input input-select input-select-line-type"
<el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key"> 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> <i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }} {{ item.name }}
</el-option> </el-option>
@ -117,18 +186,25 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">线段缓冲</span> <span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend"> <input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div> </div>
<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 class="input" type="number" title="" min="0" data-min="0.01" max="999999" <input
v-model="entityOptions.extendWidth"> class="input"
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span> <span class="unit">m</span>
<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 class="label">缓冲颜色</span> <span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div> <div class="extendColor" ref="extendColorRef"></div>
</div> </div>
@ -136,23 +212,43 @@
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13"> <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col"> <div class="col">
<span class="label">首尾反向</span> <span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate"> <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div> </div>
<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 class="input" type="number" title="" min="0" max="999999" step="1" <input
v-model="entityOptions.speed"> class="input"
type="number"
title=""
min="0"
max="999999"
step="1"
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 class="label lineSpace" <span
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" >
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"
v-model="entityOptions.space"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -161,7 +257,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">首尾相连</span> <span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail"> <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div> </div>
</div> </div>
</el-tab-pane> </el-tab-pane>
@ -173,11 +269,13 @@
</div> </div>
</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"><svg class="icon-edit"> <button @click="nodeEdit">
<use xlink:href="#yj-icon-edit"></use> <svg class="icon-edit">
</svg>二次编辑</button> <use xlink:href="#yj-icon-edit"></use></svg
<button style="margin-left: 10px;" @click="translate">平移</button> >二次编辑
</button>
<button style="margin-left: 10px" @click="translate">平移</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -186,8 +284,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'; import { ref, getCurrentInstance } from 'vue'
import { inject } from "vue"; 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'
@ -198,8 +296,8 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
@ -307,7 +405,7 @@ const activeTd = ref({
index: -1, index: -1,
name: '' name: ''
}) })
const entityOptions = ref({}); const entityOptions: any = ref({})
const linePositions = ref([]) const linePositions = ref([])
const colorRef = ref(null) const colorRef = ref(null)
const extendColorRef = ref(null) const extendColorRef = ref(null)
@ -316,7 +414,6 @@ const heightMode = ref(0)
let originalOptions let originalOptions
let that let that
const open = async (id) => { const open = async (id) => {
that = window.earth.entityMap.get(id) that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -324,11 +421,10 @@ const open = async (id) => {
heightMode.value = entityOptions.value.heightMode heightMode.value = entityOptions.value.heightMode
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
linePositions.value = structuredClone(that.options.positions) linePositions.value = structuredClone(that.options.positions)
that.lengthChangeCallBack = ()=>{ that.lengthChangeCallBack = () => {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
@ -336,28 +432,28 @@ const open = async (id) => {
baseDialog.value?.open() baseDialog.value?.open()
await nextTick() await nextTick()
let colorPicker = new YJColorPicker({ let colorPicker = new (window as any).YJColorPicker({
el: colorRef.value, el: colorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color, defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.color = color entityOptions.value.color = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)' entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调 } //点击清空按钮事件回调
}) })
let extendColorPicker = new YJColorPicker({ let extendColorPicker = new (window as any).YJColorPicker({
el: extendColorRef.value, el: extendColorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.extendColor, defaultColor: entityOptions.value.extendColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.extendColor = color entityOptions.value.extendColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -371,10 +467,15 @@ const heightModeChange = (val) => {
const heightConfirm = () => { const heightConfirm = () => {
that.positionEditing = false that.positionEditing = false
for (let i = 0; i < entityOptions.value.options.positions.length; i++) { for (let i = 0; i < entityOptions.value.options.positions.length; i++) {
entityOptions.value.options.positions[i].alt = Number((entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)) entityOptions.value.options.positions[i].alt = Number(
(entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)
)
} }
} }
const inputDblclick = async (event, i, anme) => { const inputDblclick = async (event, i, anme) => {
if (heightMode.value == 2) {
return
}
activeTd.value = { activeTd.value = {
index: i, index: i,
name: anme name: anme
@ -394,8 +495,7 @@ const inputBlurCallBack = (event, i, name, digit = 2) => {
} }
} }
const lineTypechange = () => { const lineTypechange = () => {}
}
const nodeEdit = () => { const nodeEdit = () => {
entityOptions.value.positionEditing = false entityOptions.value.positionEditing = false
entityOptions.value.noseToTail = false entityOptions.value.noseToTail = false
@ -405,8 +505,7 @@ const nodeEdit = () => {
entityOptions.value.options.positions = structuredClone(positions) entityOptions.value.options.positions = structuredClone(positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = lenByMeter / 1000 length.value = lenByMeter / 1000
} } else {
else {
length.value = lenByMeter length.value = lenByMeter
} }
}) })
@ -416,8 +515,7 @@ const translate = () => {
entityOptions.value.options.positions = structuredClone(that.options.positions) entityOptions.value.options.positions = structuredClone(that.options.positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
}) })
@ -428,7 +526,7 @@ const closeCallback = () => {
that.positionEditing = false that.positionEditing = false
entityOptions.value.closeNodeEdit() entityOptions.value.closeNodeEdit()
entityOptions.value.reset() entityOptions.value.reset()
eventBus.emit("destroyComponent") eventBus.emit('destroyComponent')
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -436,13 +534,13 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"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.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
@ -454,14 +552,13 @@ watch(
if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) { if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
}, },
{ immediate: true } { immediate: true }
); )
defineExpose({ defineExpose({
open open
}) })

View File

@ -29,15 +29,18 @@ function getFontList() {
return fontData return fontData
} }
function getFontFamily(key) { // @ts-ignore
function getFontFamily(key: any) {
for (let i = 0; i < fontData.length; i++) { for (let i = 0; i < fontData.length; i++) {
if (fontData[i].key == key) { if (fontData[i].key == key) {
return fontData[i].font; return fontData[i].font;
} }
} }
} }
function getFontFamilyName(key) { // @ts-ignore
function getFontFamilyName(key: any) {
for (let i = 0; i < fontData.length; i++) { for (let i = 0; i < fontData.length; i++) {
if (fontData[i].key == key) { if (fontData[i].key == key) {
return fontData[i].name; return fontData[i].name;

View File

@ -0,0 +1,164 @@
<template>
<Dialog ref="baseDialog" title="贴地文字属性" left="180px" top="100px" className="ground-text"
:closeCallback="closeCallback">
<template #content>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<textarea v-model="entityOptions.text"></textarea>
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color" ref="colorRef" </div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180"
v-model="entityOptions.lng">
</div>
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat">
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">旋转角度</span>
<input type="range" max="360" min="0" step="1" v-model="entityOptions.angle">
<div class="input-number input-number-unit"
style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="360" step="1"
v-model="entityOptions.angle">
<span class="unit">°</span>
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">调整大小</span>
<input type="range" max="100000" min="0" step="0.01" v-model="entityOptions.scale">
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="100000" step="0.01"
v-model="entityOptions.scale">
<span class="arrow"></span>
</div>
</div>
</div>
<div class="row">
<div class="col">
<span class="label">滚动速度</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.speed">
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="100" step="1"
v-model="entityOptions.speed">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<div style="position: absolute; left: 24px; display: flex;">
<button style="margin-left: 10px;" @click="translate"><svg class="icon-py">
<use xlink:href="#yj-icon-py"></use>
</svg>平移</button>
</div>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { inject } from "vue";
import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue'
import { initMapData } from '../tree/initMapData'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const baseDialog: any = ref(null);
const eventBus: any = inject("bus");
const text = ref("")
eventBus.on("openStandTextAdd", () => {
baseDialog.value?.open()
});
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const colorRef = ref(null)
const open = async (id: any) => {
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
let colorPicker = new window.YJColorPicker({
el: colorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.color = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
// 删除不必要的属性
delete params.host
delete params.name
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0,
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
entityOptions.value.remove()
close()
}
const translate = () => {
entityOptions.value.positionEditing = true
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
that.reset()
eventBus?.emit("destroyComponent")
}
defineExpose({
open
})
</script>
<style scoped lang="scss"></style>

View File

@ -3,7 +3,7 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">新增{{ type }}标签风格设置</span> <span class="label">新增{{ type }}标签风格设置</span>
<button style="margin-right: 56px;">初始风格</button> <button style="margin-right: 56px">初始风格</button>
<button>当前风格</button> <button>当前风格</button>
</div> </div>
</div> </div>
@ -11,20 +11,27 @@
<div class="row"></div> <div class="row"></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>
<span class="label">标签显示</span> <span class="label">标签显示</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow" />
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px;"> <div class="col" style="flex: 0 0 114px">
<span class="label">视野缩放</span> <span class="label">视野缩放</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance"> <input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance" />
</div> </div>
<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 class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelNear"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
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,7 +39,14 @@
<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 class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelFar"> <input
class="input"
type="number"
title=""
min="1"
max="99999999"
v-model="entityOptions.labelFar"
/>
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -46,20 +60,27 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col" style="flex: 0 0 114px;"> <div class="col" style="flex: 0 0 114px">
<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 class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize"> <input
class="input"
type="number"
title=""
min="1"
max="99"
v-model="entityOptions.labelFontSize"
/>
<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 font-select-box"> <div class="col font-select-box">
<span class="label" style="flex: none;">字体选择</span> <span class="label" style="flex: none">字体选择</span>
<el-select class="input input-select font-select" v-model="entityOptions.labelFontFamily"> <el-select class="input input-select font-select" v-model="entityOptions.labelFontFamily">
<el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key"> <el-option v-for="item in fontList" :key="item.key" :label="item.name" :value="item.key">
</el-option> </el-option>
@ -76,8 +97,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue'
import { inject } from "vue"; import { inject } from 'vue'
import { getFontList } from './fontSelect' import { getFontList } from './fontSelect'
const props = defineProps({ const props = defineProps({
@ -99,14 +120,14 @@ const fontChange = (val) => {
} }
onMounted(() => { onMounted(() => {
let labelColorPicker = new YJColorPicker({ let labelColorPicker = new (window as any).YJColorPicker({
el: labelColorRef.value, el: labelColorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.labelColor, defaultColor: entityOptions.value.labelColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.labelColor = color entityOptions.value.labelColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {

View File

@ -1,20 +1,24 @@
<template> <template>
<Dialog ref="baseDialog" title="属性" left="180px" top="100px" :closeCallback="closeCallback"> <Dialog ref="baseDialog" :title="title+'属性'" left="180px" top="100px" className="polygon" :closeCallback="closeCallback">
<template #content> <template #content>
<span class="custom-divider"></span> <span class="custom-divider"></span>
<div class="div-item"> <div class="div-item">
<div class="row" style="align-items: flex-start;"> <div class="row" style="align-items: flex-start;">
<div class="col"> <div class="col">
<span class="label">名称</span> <span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="options.name"> <input class="input" maxlength="40" type="text" v-model="entityOptions.name">
</div> </div>
<div class="col" style="flex: 0 0 60%;"> <div class="col" style="flex: 0 0 60%;">
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col input-select-unit-box">
<span class="label" style="margin-right: 0px;">投影面积:</span> <span class="label" style="margin-right: 0px;">投影面积:</span>
<input class="input input-text" readonly="readonly" type="text"> <input class="input input-text" readonly type="text" v-model="area">
<div class="input-select-unit"></div> <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>
@ -22,24 +26,29 @@
</div> </div>
<div class="div-item"> <div class="div-item">
<div class="row"> <div class="row">
<el-tabs v-model="activeName" @tab-click="handleClick"> <el-tabs v-model="activeName">
<el-tab-pane label="属性信息" name="1"> <el-tab-pane label="属性信息" name="1">
<attribute></attribute> <attribute :entityOptions="entityOptions"></attribute>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<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>
<div class="height-mode"></div> <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>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box"> <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"> <input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height">
<span class="unit">m</span> <span class="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button class="confirm height-confirm" style="margin-left: 5px;">确认</button> <button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm"
:disabled="heightMode == 2">应用</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -53,6 +62,25 @@
</div> </div>
</div> </div>
<div class="table-body"> <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" 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" 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="entityOptions.height" min="-9999999" max="999999999"
v-if="activeTd.index == i && activeTd.name == 'alt'">
<span style="pointer-events: none;" v-else>{{ (entityOptions.height).toFixed(2) }}</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -70,21 +98,32 @@
<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 class="input" type="number" title="" min="0" max="99" @model="lineWidth"> <input class="input" type="number" title="" min="0" max="99" 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> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="标签风格" name="5">角色管理</el-tab-pane> <el-tab-pane label="标签风格" name="4">
<labelStyle :type="title" :entityOptions="entityOptions"></labelStyle>
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div> </div>
<span class="custom-divider"></span> <span class="custom-divider"></span>
</template> </template>
<template #footer> <template #footer>
<button>确定</button> <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> </template>
</Dialog> </Dialog>
</template> </template>
@ -92,12 +131,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { inject } from "vue"; import { inject } from "vue";
import { TreeApi } from '@/api/tree'
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 labelStyle from './labelStyle.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const activeName = ref('1') const { cusUpdateNode } = useTreeNode()
const baseDialog = ref(null);
const eventBus = inject("bus"); const title = ref('面')
const baseDialog: any = ref(null);
const eventBus: any = inject("bus");
const options = ref({}); const options = ref({});
const colorRef = ref(null) const colorRef = ref(null)
const lineColorRef = ref(null) const lineColorRef = ref(null)
@ -105,107 +149,192 @@ eventBus.on("openPolygonEdit", () => {
baseDialog.value?.open() baseDialog.value?.open()
}); });
const lineWidth = ref('') 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 open = async (id) => { const activeName = ref('1')
let that = window.earth.entityMap.get(id) const activeTd = ref({
options.value = structuredClone(that.options) index: -1,
name: ''
})
const positions = ref([])
const heightMode = ref(0)
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const open = async (id: any, type: any) => {
if(type && type === 'rectangle') {
title.value = '矩形'
}
else if(type && type === 'rendezvous') {
title.value = '集结地'
}
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
heightMode.value = entityOptions.value.heightMode
area.value = entityOptions.value.areaByMeter
positions.value = structuredClone(that.options.positions)
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() baseDialog.value?.open()
await nextTick() await nextTick()
let colorPicker = new YJColorPicker({ let colorPicker = new window.YJColorPicker({
el: colorRef.value, el: colorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: options.value.color, defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: color => {
options.value.color = color entityOptions.value.color = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
options.value.color = 'rgba(255,255,255,1)' entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调 } //点击清空按钮事件回调
}) })
let linecolorPicker = new YJColorPicker({ let linecolorPicker = new window.YJColorPicker({
el: lineColorRef.value, el: lineColorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: options.value.lineColor, defaultColor: entityOptions.value.lineColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: color => {
options.value.lineColor = color entityOptions.value.lineColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
options.value.lineColor = 'rgba(255,255,255,1)' entityOptions.value.lineColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调 } //点击清空按钮事件回调
}) })
let labelColorPicker = new YJColorPicker({
el: contentElm.getElementsByClassName('labelColor')[0],
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: this.labelColor,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
this.labelColor = color
}, //点击确认按钮事件回调
clear: () => {
this.labelColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
let lineColorPicker = new YJColorPicker({
el: contentElm.getElementsByClassName('labelLineColor')[0],
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: this.labelLineColor,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
this.labelLineColor = color
}, //点击确认按钮事件回调
clear: () => {
this.labelLineColor = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
let labelBackgroundColorStartPicker = new YJColorPicker({
el: contentElm.getElementsByClassName('labelBackgroundColorStart')[0],
size: 'mini',
alpha: true,
defaultColor: this.labelBackgroundColorStart,
disabled: false,
openPickerAni: 'opacity',
sure: color => {
this.labelBackgroundColorStart = color
},
clear: () => {
this.labelBackgroundColorStart = 'rgba(255,255,255,1)'
}
})
let labelBackgroundColorEndPicker = new YJColorPicker({
el: contentElm.getElementsByClassName('labelBackgroundColorEnd')[0],
size: 'mini',
alpha: true,
defaultColor: this.labelBackgroundColorEnd,
disabled: false,
openPickerAni: 'opacity',
sure: color => {
this.labelBackgroundColorEnd = color
},
clear: () => {
this.labelBackgroundColorEnd = 'rgba(255,255,255,1)'
}
})
} }
const handleClick = () => { } 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.positions = structuredClone(that.options.positions)
})
}
const closeCallback = () => { const closeCallback = () => {
console.log('closeCallback'); entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
entityOptions.value.closeNodeEdit()
entityOptions.value.reset()
eventBus.emit("destroyComponent")
} }
const nodeEdit = () => {
that.nodeEdit((e, positions, areaByMeter) => {
console.log('positions', positions)
entityOptions.value.options.positions = structuredClone(positions)
})
}
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({ defineExpose({
open open
}) })

View File

@ -1,14 +1,21 @@
<template> <template>
<Dialog ref="baseDialog" title="线标注" left="180px" top="100px" className="polyline" :closeCallback="closeCallback"> <Dialog
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">
<div class="row" style="align-items: flex-start;"> <div class="row" style="align-items: flex-start">
<div class="col"> <div class="col">
<span class="label">名称</span> <span class="label">名称</span>
<input class="input" maxlength="40" type="text" v-model="entityOptions.name"> <input class="input" maxlength="40" type="text" v-model="entityOptions.name" />
</div> </div>
<div class="col" style="flex: 0 0 56%;"> <div class="col" style="flex: 0 0 56%">
<div> <div>
<div class="row"> <div class="row">
<div class="col input-select-unit-box"> <div class="col input-select-unit-box">
@ -17,7 +24,7 @@
<el-option label="投影长度" :value="1"></el-option> <el-option label="投影长度" :value="1"></el-option>
<el-option label="地表长度" :value="2"></el-option> <el-option label="地表长度" :value="2"></el-option>
</el-select> </el-select>
<input v-model="length" class="input-text" readonly="readonly"> <input v-model="length" class="input-text" readonly />
<el-select v-model="lengthUnit"> <el-select v-model="lengthUnit">
<el-option label="米" value="m"></el-option> <el-option label="米" value="m"></el-option>
<el-option label="千米" value="km"></el-option> <el-option label="千米" value="km"></el-option>
@ -37,22 +44,48 @@
<el-tab-pane label="空间信息" name="2"> <el-tab-pane label="空间信息" name="2">
<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 class="input input-select height-mode-scelect" style="width: 155px;margin-left: 20px" <el-select
v-model="heightMode" @change="heightModeChange" placeholder="请选择"> class="input input-select height-mode-scelect"
<el-option v-for="item in heightModeData" :key="item.key" :label="item.name" :value="item.key"> 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-option>
</el-select> </el-select>
</div> </div>
<div class="col"> <div class="col">
<span class="label">Z值统一增加</span> <span class="label">Z值统一增加</span>
<div class="input-number input-number-unit-1 height-box" :class="{ 'disabled': heightMode == 2 }"> <div
<input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height"> 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="unit">m</span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
<button class="confirm height-confirm" style="margin-left: 5px;" @click="heightConfirm" <button
:disabled="heightMode == 2">应用</button> class="confirm height-confirm"
style="margin-left: 5px"
@click="heightConfirm"
:disabled="heightMode == 2"
>
应用
</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -69,20 +102,40 @@
<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 class="input" @blur="inputBlurCallBack($event, i, 'lng', 8)" type="number" <input
v-model="item.lng" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lng'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lng).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lng', 8)"
type="number"
v-model="item.lng"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lng'"
/>
<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 class="input" @blur="inputBlurCallBack($event, i, 'lat', 8)" type="number" <input
v-model="item.lat" min="-180" max="180" v-if="activeTd.index == i && activeTd.name == 'lat'"> class="input"
<span style="pointer-events: none;" v-else>{{ (item.lat).toFixed(8) }}</span> @blur="inputBlurCallBack($event, i, 'lat', 8)"
type="number"
v-model="item.lat"
min="-180"
max="180"
v-if="activeTd.index == i && activeTd.name == 'lat'"
/>
<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 class="input" @blur="inputBlurCallBack($event, i, 'alt', 2)" type="number" <input
v-model="item.alt" min="-9999999" max="999999999" class="input"
v-if="activeTd.index == i && activeTd.name == 'alt'"> @blur="inputBlurCallBack($event, i, 'alt', 2)"
<span style="pointer-events: none;" v-else>{{ (item.alt).toFixed(2) }}</span> type="number"
v-model="item.alt"
min="-9999999"
max="999999999"
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> </div>
@ -95,19 +148,35 @@
<span class="label">线条颜色</span> <span class="label">线条颜色</span>
<div class="color" ref="colorRef"></div> <div class="color" ref="colorRef"></div>
</div> </div>
<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 class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth"> <input
class="input"
type="number"
title=""
min="1"
max="999"
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 class="input input-select input-select-line-type" style="margin-left: 20px" <el-select
v-model="entityOptions.lineType" @change="lineTypechange"> class="input input-select input-select-line-type"
<el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key"> 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> <i class="yj-custom-icon" :class="item.icon"></i>
{{ item.name }} {{ item.name }}
</el-option> </el-option>
@ -117,30 +186,36 @@
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">首尾相连</span> <span class="label">首尾相连</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail"> <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail" />
</div> </div>
<div class="col" style="flex: 0 0 33%;"> <div class="col" style="flex: 0 0 33%">
<span class="label">线段圆滑</span> <span class="label">线段圆滑</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.smooth"> <input class="btn-switch" type="checkbox" v-model="entityOptions.smooth" />
</div>
<div class="col" style="flex: 0 0 37%;">
</div> </div>
<div class="col" style="flex: 0 0 37%"></div>
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<span class="label">线段缓冲</span> <span class="label">线段缓冲</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.extend"> <input class="btn-switch" type="checkbox" v-model="entityOptions.extend" />
</div> </div>
<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 class="input" type="number" title="" min="0" data-min="0.01" max="999999" <input
v-model="entityOptions.extendWidth"> class="input"
type="number"
title=""
min="0"
data-min="0.01"
max="999999"
v-model="entityOptions.extendWidth"
/>
<span class="unit">m</span> <span class="unit">m</span>
<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 class="label">缓冲颜色</span> <span class="label">缓冲颜色</span>
<div class="extendColor" ref="extendColorRef"></div> <div class="extendColor" ref="extendColorRef"></div>
</div> </div>
@ -148,23 +223,43 @@
<div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13"> <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
<div class="col"> <div class="col">
<span class="label">首尾反向</span> <span class="label">首尾反向</span>
<input class="btn-switch" type="checkbox" v-model="entityOptions.rotate"> <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate" />
</div> </div>
<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 class="input" type="number" title="" min="0" max="999999" step="1" <input
v-model="entityOptions.speed"> class="input"
type="number"
title=""
min="0"
max="999999"
step="1"
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 class="label lineSpace" <span
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" >
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"
v-model="entityOptions.space"
/>
<span class="unit"></span> <span class="unit"></span>
<span class="arrow"></span> <span class="arrow"></span>
</div> </div>
@ -179,11 +274,17 @@
</div> </div>
</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"><svg class="icon-edit"> <button @click="nodeEdit">
<use xlink:href="#yj-icon-edit"></use> <svg class="icon-edit">
</svg>二次编辑</button> <use xlink:href="#yj-icon-edit"></use></svg
<button style="margin-left: 10px;" @click="translate">平移</button> >二次编辑
</button>
<button style="margin-left: 10px" @click="translate">
<svg class="icon-py">
<use xlink:href="#yj-icon-py"></use></svg
>平移
</button>
</div> </div>
<button @click="confirm">确定</button> <button @click="confirm">确定</button>
<button @click="close">关闭</button> <button @click="close">关闭</button>
@ -192,24 +293,21 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'; import { ref, getCurrentInstance } from 'vue'
import { inject } from "vue"; 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 { getFontList } from './fontSelect'
import attribute from './attribute.vue' import attribute from './attribute.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'
const { cusUpdateNode } = useTreeNode() const { cusUpdateNode } = useTreeNode()
const baseDialog = ref(null); const baseDialog: any = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
const length = ref(0) const length = ref(0)
const lengthUnit = ref('m') const lengthUnit = ref('m')
const fontList = ref(getFontList())
const height = ref(10) const height = ref(10)
const heightModeData = ref([ const heightModeData = ref([
{ {
@ -313,28 +411,26 @@ const activeTd = ref({
index: -1, index: -1,
name: '' name: ''
}) })
const entityOptions = ref({}); const entityOptions: any = ref({})
const linePositions = ref([]) const linePositions = ref([])
const colorRef = ref(null) const colorRef = ref(null)
const extendColorRef = ref(null) const extendColorRef = ref(null)
const heightMode = ref(0) const heightMode = ref(0)
let originalOptions let originalOptions: any
let that let that: any
const open = async (id: any) => {
const open = async (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
heightMode.value = entityOptions.value.heightMode heightMode.value = entityOptions.value.heightMode
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
linePositions.value = structuredClone(that.options.positions) linePositions.value = structuredClone(that.options.positions)
that.lengthChangeCallBack = ()=>{ that.lengthChangeCallBack = () => {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
@ -342,28 +438,28 @@ const open = async (id) => {
baseDialog.value?.open() baseDialog.value?.open()
await nextTick() await nextTick()
let colorPicker = new YJColorPicker({ let colorPicker = new (window as any).YJColorPicker({
el: colorRef.value, el: colorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color, defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.color = color entityOptions.value.color = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)' entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调 } //点击清空按钮事件回调
}) })
let extendColorPicker = new YJColorPicker({ let extendColorPicker = new (window as any).YJColorPicker({
el: extendColorRef.value, el: extendColorRef.value,
size: 'mini', //颜色box类型 size: 'mini', //颜色box类型
alpha: true, //是否开启透明度 alpha: true, //是否开启透明度
defaultColor: entityOptions.value.extendColor, defaultColor: entityOptions.value.extendColor,
disabled: false, //是否禁止打开颜色选择器 disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画 openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => { sure: (color) => {
entityOptions.value.extendColor = color entityOptions.value.extendColor = color
}, //点击确认按钮事件回调 }, //点击确认按钮事件回调
clear: () => { clear: () => {
@ -377,11 +473,16 @@ const heightModeChange = (val) => {
const heightConfirm = () => { const heightConfirm = () => {
that.positionEditing = false that.positionEditing = false
for (let i = 0; i < entityOptions.value.options.positions.length; i++) { for (let i = 0; i < entityOptions.value.options.positions.length; i++) {
entityOptions.value.options.positions[i].alt = Number((entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)) entityOptions.value.options.positions[i].alt = Number(
(entityOptions.value.options.positions[i].alt + Number(height.value)).toFixed(2)
)
} }
that.smooth = that.smooth that.smooth = that.smooth
} }
const inputDblclick = async (event, i, anme) => { const inputDblclick = async (event, i, anme) => {
if (heightMode.value == 2) {
return
}
activeTd.value = { activeTd.value = {
index: i, index: i,
name: anme name: anme
@ -401,8 +502,7 @@ const inputBlurCallBack = (event, i, name, digit = 2) => {
} }
} }
const lineTypechange = () => { const lineTypechange = () => {}
}
const nodeEdit = () => { const nodeEdit = () => {
entityOptions.value.positionEditing = false entityOptions.value.positionEditing = false
entityOptions.value.noseToTail = false entityOptions.value.noseToTail = false
@ -412,8 +512,7 @@ const nodeEdit = () => {
entityOptions.value.options.positions = structuredClone(positions) entityOptions.value.options.positions = structuredClone(positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = lenByMeter / 1000 length.value = lenByMeter / 1000
} } else {
else {
length.value = lenByMeter length.value = lenByMeter
} }
}) })
@ -423,8 +522,7 @@ const translate = () => {
entityOptions.value.options.positions = structuredClone(that.options.positions) entityOptions.value.options.positions = structuredClone(that.options.positions)
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
}) })
@ -435,7 +533,7 @@ const closeCallback = () => {
that.positionEditing = false that.positionEditing = false
entityOptions.value.closeNodeEdit() entityOptions.value.closeNodeEdit()
entityOptions.value.reset() entityOptions.value.reset()
eventBus.emit("destroyComponent") eventBus.emit('destroyComponent')
} }
const confirm = () => { const confirm = () => {
originalOptions = structuredClone(that.options) originalOptions = structuredClone(that.options)
@ -443,13 +541,13 @@ const confirm = () => {
let params = structuredClone(that.options) let params = structuredClone(that.options)
delete params.host delete params.host
let params2 = { let params2 = {
"id": params.id, id: params.id,
"sourceName": params.name, sourceName: params.name,
"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.name, params: JSON.stringify(params) })
} }
const close = () => { const close = () => {
baseDialog.value?.close() baseDialog.value?.close()
@ -461,14 +559,13 @@ watch(
if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) { if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
if (lengthUnit.value == 'km') { if (lengthUnit.value == 'km') {
length.value = entityOptions.value.lengthByMeter / 1000 length.value = entityOptions.value.lengthByMeter / 1000
} } else {
else {
length.value = entityOptions.value.lengthByMeter length.value = entityOptions.value.lengthByMeter
} }
} }
}, },
{ immediate: true } { immediate: true }
); )
defineExpose({ defineExpose({
open open
}) })

View File

@ -10,7 +10,7 @@
<div ref="editorContainer" id="editor-container"></div> <div ref="editorContainer" id="editor-container"></div>
<div class="richText-footer"> <div class="richText-footer">
<button class="primary" @click="confirm">确认</button> <button class="primary" @click="confirm">确认</button>
<button class="cancel">取消</button> <button class="cancel" @click="close">取消</button>
</div> </div>
</div> </div>
</div> </div>
@ -26,8 +26,8 @@ const props = defineProps({
const host = window.location.host const host = window.location.host
const visible = ref(false) const visible = ref(false)
const baseDialog = ref(null); const baseDialog:any = ref(null);
const eventBus = inject("bus"); const eventBus:any = inject("bus");
const toolbarContainer = ref() const toolbarContainer = ref()
const editorContainer = ref() const editorContainer = ref()
@ -50,7 +50,7 @@ const open = (t = '', content = '') => {
title.value = t title.value = t
visible.value = true visible.value = true
nextTick(() => { nextTick(() => {
const { createEditor, createToolbar } = window.wangEditor const { createEditor, createToolbar } = (window as any).wangEditor
const editorConfig = { const editorConfig = {
placeholder: '请输入正文...', placeholder: '请输入正文...',
MENU_CONF: { MENU_CONF: {

View File

@ -1,10 +1,44 @@
<template> <template>
<Dialog ref="baseDialog" title="贴地文字" left="180px" top="100px"> <Dialog ref="baseDialog" title="立体t文字属性" left="180px" top="100px" className="ground-text"
:closeCallback="closeCallback">
<template #content> <template #content>
<textarea style="height: 76px; width: 270px;"></textarea> <span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">名称</span>
<textarea v-model="entityOptions.text"></textarea>
</div>
<div class="col">
<span class="label">颜色</span>
<div class="color" ref="colorRef" </div>
</div>
</div>
</div>
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
<div class="col">
<span class="label">滚动速度</span>
<input type="range" max="100" min="0" step="1" v-model="entityOptions.speed">
<div class="input-number" style="width: 100px;flex: 0 0 100px;margin-left: 10px;">
<input class="input" type="number" title="" min="0" max="100" step="1" v-model="entityOptions.speed">
<span class="arrow"></span>
</div>
</div>
</div>
</div>
<span class="custom-divider"></span>
</template> </template>
<template #footer> <template #footer>
<button>确定</button> <div style="position: absolute; left: 24px; display: flex;">
<button @click="nodeEdit"><svg class="icon-edit">
<use xlink:href="#yj-icon-edit"></use>
</svg>二次编辑</button>
</div>
<button @click="remove">删除</button>
<button @click="confirm">确定</button>
<button @click="close">关闭</button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -12,13 +46,78 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { inject } from "vue"; import { inject } from "vue";
import { TreeApi } from '@/api/tree'
import Dialog from '@/components/dialog/baseDialog.vue' import Dialog from '@/components/dialog/baseDialog.vue'
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
const { cusUpdateNode } = useTreeNode()
const baseDialog = ref(null); const baseDialog: any = ref(null);
const eventBus = inject("bus"); const eventBus: any = inject("bus");
eventBus.on("openDialog", () => { eventBus.on("openStandTextAdd", () => {
baseDialog.value?.open() baseDialog.value?.open()
}); });
const entityOptions: any = ref({});
let originalOptions: any
let that: any
const colorRef = ref(null)
const open = async (id: any) => {
that = window.earth.entityMap.get(id)
originalOptions = structuredClone(that.options)
entityOptions.value = that
baseDialog.value?.open()
await nextTick()
let colorPicker = new window.YJColorPicker({
el: colorRef.value,
size: 'mini', //颜色box类型
alpha: true, //是否开启透明度
defaultColor: entityOptions.value.color,
disabled: false, //是否禁止打开颜色选择器
openPickerAni: 'opacity', //打开颜色选择器动画
sure: color => {
entityOptions.value.color = color
}, //点击确认按钮事件回调
clear: () => {
entityOptions.value.color = 'rgba(255,255,255,1)'
} //点击清空按钮事件回调
})
}
const confirm = () => {
originalOptions = structuredClone(that.options)
baseDialog.value?.close()
let params = structuredClone(that.options)
// 删除不必要的属性
delete params.host
delete params.name
let params2 = {
"id": params.id,
"sourceName": params.name,
"params": params,
"isShow": params.show ? 1 : 0,
}
TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({ "id": params.id, "sourceName": params.name, "params": JSON.stringify(params) })
}
const close = () => {
baseDialog.value?.close()
}
const remove = () => {
that.remove()
close()
}
const nodeEdit = () => {
that.nodeEdit()
}
const closeCallback = () => {
entityOptions.value.originalOptions = structuredClone(originalOptions)
that.positionEditing = false
that.reset()
eventBus?.emit("destroyComponent")
}
defineExpose({
open
})
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@ -11,26 +11,25 @@ export const useRightOperate = () => {
$changeComponentPop('.adddirectoryBox', true) $changeComponentPop('.adddirectoryBox', true)
} }
//添加资源 //添加资源
const addResource = () => {} const addResource = () => { }
//导入全景 //导入全景
const importPanorama = () => {} const importPanorama = () => { }
//图片定位 //图片定位
const pictureLocation = () => {} const pictureLocation = () => { }
//属性 //属性
const showAttr = () => {} const showAttr = () => { }
//导入模型 //导入模型
const importHeader = () => {} const importHeader = () => { }
//导入模型 //导入模型
const addXlsxs = () => {} const addXlsxs = () => { }
//导入模型 //导入模型
const addTrajectory = () => {} const addTrajectory = () => { }
//编辑 //编辑
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]) {
let params = JSON.parse(selectNodes[selectNodes.length-1].params) let params = JSON.parse(selectNodes[selectNodes.length - 1].params)
console.log('params', params) eventBus.emit("openDialog", selectNodes[selectNodes.length - 1].sourceType, params.id);
eventBus.emit("openDialog", selectNodes[selectNodes.length-1].sourceType, params.id);
} }
} }
//删除 //删除
@ -62,17 +61,17 @@ export const useRightOperate = () => {
}) })
} }
//添加BIM //添加BIM
const addBIM = () => {} const addBIM = () => { }
//重置透视 //重置透视
const resetPerspective = () => {} const resetPerspective = () => { }
const pressModel = () => {} const pressModel = () => { }
//设置视图 //设置视图
const setView = () => { const setView = () => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
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)
let entityObject = window.earth.entityMap.get(params.id) let entityObject = window.earth.entityMap.get(params.id)
entityObject.setCustomView() entityObject.setCustomView()
@ -92,8 +91,8 @@ export const useRightOperate = () => {
//重置视图 //重置视图
const resetView = () => { const resetView = () => {
let selectNodes = getSelectedNodes(window.treeObj); let selectNodes = getSelectedNodes(window.treeObj);
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)
let entityObject = window.earth.entityMap.get(params.id) let entityObject = window.earth.entityMap.get(params.id)
entityObject.resetCustomView() entityObject.resetCustomView()
@ -108,19 +107,19 @@ export const useRightOperate = () => {
"isShow": node.isShow ? 1 : 0, "isShow": node.isShow ? 1 : 0,
} }
TreeApi.updateDirectoryInfo(params2) TreeApi.updateDirectoryInfo(params2)
cusUpdateNode({"id": params2.id, "sourceName": params2.sourceName, "params": JSON.stringify(params)}) cusUpdateNode({ "id": params2.id, "sourceName": params2.sourceName, "params": JSON.stringify(params) })
} }
} }
//提升图层 //提升图层
const layerRaise = () => {} const layerRaise = () => { }
//降低图层 //降低图层
const layerLower = () => {} const layerLower = () => { }
//置顶图层 //置顶图层
const layerToTop = () => {} const layerToTop = () => { }
//置底图层 //置底图层
const layerToBottom = () => {} const layerToBottom = () => { }
//切片 //切片
const tilesetClipping = () => {} const tilesetClipping = () => { }
const rightMenus: any = reactive({ const rightMenus: any = reactive({
addDirectory: { addDirectory: {
key: 'addDirectory', key: 'addDirectory',

View File

@ -384,13 +384,9 @@ export const useTree = () => {
id: 1, id: 1,
parentId: 0, parentId: 0,
sourceName: '111', sourceName: '111',
isShow: true isShow: true,
}, sourceType: '',
{ params: ''
id: 2,
parentId: 0,
sourceName: '222',
isShow: true
} }
]) ])
@ -407,13 +403,27 @@ export const useTree = () => {
const initTree = async (selector: string = '#treeDemo') => { const initTree = async (selector: string = '#treeDemo') => {
let res = await TreeApi.getTreeList() let res = await TreeApi.getTreeList()
console.log('res', res) console.log('res', res)
if ([0,200].includes(res.code)) { if ([0, 200].includes(res.code)) {
res.data.sort((a: any, b: any) => { res.data.sort((a: any, b: any) => {
if(a.treeIndex&&b.treeIndex) if (a.treeIndex && b.treeIndex) {
return a.treeIndex - b.treeIndex return a.treeIndex - b.treeIndex
}
if (a.treeIndex) {
return -1;
}
if (b.treeIndex) {
return 1;
}
return 0;
}) })
for (let i = res.data.length - 1; i >= 0; i--) {
if (!res.data[i].id) {
res.data.splice(i, 1);
}
}
zNodes.value = res.data zNodes.value = res.data
treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value) treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value)
console.log(res.data)
window.treeObj = treeObj.value window.treeObj = treeObj.value
window.AllNodes = treeObj.value.getNodes() window.AllNodes = treeObj.value.getNodes()
initTreeCallBack() initTreeCallBack()

View File

@ -2,6 +2,12 @@ export const initMapData = async (type, data) => {
let entityObject let entityObject
let options let options
switch (type) { switch (type) {
case 'groundText':
entityObject = new YJ.Obj.GroundText(window.earth, data)
break
case 'standText':
entityObject = new YJ.Obj.StandText(window.earth, data)
break
case 'point': case 'point':
entityObject = new YJ.Obj.BillboardObject(window.earth, data) entityObject = new YJ.Obj.BillboardObject(window.earth, data)
break break
@ -11,21 +17,22 @@ export const initMapData = async (type, data) => {
case 'curve': case 'curve':
entityObject = await new YJ.Obj.CurvelineObject(window.earth, data) entityObject = await new YJ.Obj.CurvelineObject(window.earth, data)
break break
case 'polygon': case 'panel':
case 'rectangle':
entityObject = new YJ.Obj.PolygonObject(window.earth, data) entityObject = new YJ.Obj.PolygonObject(window.earth, data)
break break
case 'groundText': case 'rendezvous':
entityObject = new YJ.Obj.GroundText(window.earth, data) entityObject = new YJ.Obj.AssembleObject(window.earth, data)
break break
case 'standText': case 'attackArrow':
entityObject = new YJ.Obj.StandText(window.earth, data) entityObject = new YJ.Obj.AttackArrowObject(window.earth, data)
break
case 'pincerArrow':
entityObject = new YJ.Obj.PincerArrowObject(window.earth, data)
break break
case 'circle': case 'circle':
entityObject = new YJ.Obj.CircleObject(window.earth, data) entityObject = new YJ.Obj.CircleObject(window.earth, data)
break break
case 'rectangle':
entityObject = new YJ.Obj.RectangleObject(window.earth, data)
break
case 'ellipse': case 'ellipse':
entityObject = new YJ.Obj.EllipseObject(window.earth, data) entityObject = new YJ.Obj.EllipseObject(window.earth, data)
break break

View File

@ -9,27 +9,19 @@
<!--左侧一级菜单--> <!--左侧一级菜单-->
<firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu> <firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
<!--底部菜单--> <!--底部菜单-->
<!-- 多点视线分析 -->
<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>
<bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu> <bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
<input type="file" id="fileInputlink" style="display: none;" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf" <input
@input="uploadFile"> type="file"
id="fileInputlink"
style="display: none"
multiple
accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { inject, shallowRef, ref } from "vue"; import { inject, shallowRef, ref } from 'vue'
import Headers from '../components/headers/index.vue' import Headers from '../components/headers/index.vue'
import Tree from '../components/tree/index.vue' import Tree from '../components/tree/index.vue'
import addStandText from '../components/propertyBox/addStandText.vue' import addStandText from '../components/propertyBox/addStandText.vue'
@ -38,84 +30,95 @@ import billboardObject from '../components/propertyBox/billboardObject.vue'
import polygonObject from '../components/propertyBox/polygonObject.vue' import polygonObject from '../components/propertyBox/polygonObject.vue'
import polylineObject from '../components/propertyBox/polylineObject.vue' import polylineObject from '../components/propertyBox/polylineObject.vue'
import curvelineObject from '../components/propertyBox/curvelineObject.vue' import curvelineObject from '../components/propertyBox/curvelineObject.vue'
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 standText from '../components/propertyBox/standText.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 { GisApi } from '@/api/gisApi' import { GisApi } from '@/api/gisApi'
const firstMenuRef = ref(null) const firstMenuRef = ref(null)
const bottomMenuRef = ref(null) const bottomMenuRef = ref(null)
const eventBus = inject("bus"); const eventBus: any = inject('bus')
let currentComponent = shallowRef() let currentComponent = shallowRef()
let dynamicComponentRef = ref() let dynamicComponentRef = ref()
let addStandTextRef = ref() let addStandTextRef = ref()
let tree = ref() let tree = ref()
eventBus.on("openDialog", async (sourceType: any, id: any) => { eventBus.on('openDialog', async (sourceType: any, id: any) => {
switch (sourceType) { switch (sourceType) {
case 'groundText': case 'addGroundText':
currentComponent.value = addGroundText currentComponent.value = addGroundText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'standText': case 'groundText':
currentComponent.value = groundText
await nextTick()
dynamicComponentRef.value?.open()
break
case 'addStandText':
currentComponent.value = addStandText currentComponent.value = addStandText
await nextTick() await nextTick()
dynamicComponentRef.value?.open() dynamicComponentRef.value?.open()
break; break
case 'standText':
currentComponent.value = standText
await nextTick()
dynamicComponentRef.value?.open()
break
case 'point': case 'point':
currentComponent.value = billboardObject currentComponent.value = billboardObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'line': case 'line':
currentComponent.value = polylineObject currentComponent.value = polylineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'curve': case 'curve':
currentComponent.value = curvelineObject currentComponent.value = curvelineObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
break; break
case 'panel': case 'panel':
currentComponent.value = polygonObject currentComponent.value = polygonObject
await nextTick() await nextTick()
dynamicComponentRef.value?.open(id) dynamicComponentRef.value?.open(id)
break; break
case 'circle': case 'circle':
break; break
case 'rectangle': case 'rectangle':
break; currentComponent.value = polygonObject
await nextTick()
dynamicComponentRef.value?.open(id, 'rectangle')
break
case 'rendezvous': case 'rendezvous':
break; currentComponent.value = rendezvous
await nextTick()
dynamicComponentRef.value?.open(id, 'rendezvous')
break
case 'attackArrow': case 'attackArrow':
break; currentComponent.value = attackArrow
await nextTick()
dynamicComponentRef.value?.open(id, 'attackArrow')
break
case 'pincerArrow': case 'pincerArrow':
break; currentComponent.value = attackArrow
await nextTick()
dynamicComponentRef.value?.open(id, 'pincerArrow')
break
default: default:
break; break
} }
}); })
eventBus.on("destroyComponent",()=>{ eventBus.on('destroyComponent', () => {
currentComponent.value = undefined currentComponent.value = undefined
}) })
const createEarth = async () => { const createEarth = async () => {
window.earth = await new YJ.YJEarth('earthContainer') window.earth = await new YJ.YJEarth('earthContainer')
tree.value.initTreeCallBack() tree.value.initTreeCallBack()
@ -136,16 +139,15 @@ eventBus.on('defineClickAddLinkCb', (fun) => {
clickAddLinkCb = fun clickAddLinkCb = fun
}) })
const uploadFile = (event) => { const uploadFile = (event) => {
let files = event.target.files let files = event.target.files
if (files.length > 0) { if (files.length > 0) {
const formData = new FormData(); const formData = new FormData()
for (let i = 0; i < files.length; i++) { for (let i = 0; i < files.length; i++) {
const element = files[i]; const element = files[i]
formData.append('files', element); formData.append('files', element)
} }
GisApi.linkFile(formData).then(res => { GisApi.linkFile(formData).then((res) => {
if (res.code == 0 || res.code == 200) { if (res.code == 0 || res.code == 200) {
ElMessage({ ElMessage({
message: '上传成功', message: '上传成功',