Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl
This commit is contained in:
		
							
								
								
									
										1
									
								
								src/renderer/components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/renderer/components.d.ts
									
									
									
									
										vendored
									
									
								
							@ -27,6 +27,7 @@ declare module 'vue' {
 | 
			
		||||
    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
 | 
			
		||||
    ElTabPane: typeof import('element-plus/es')['ElTabPane']
 | 
			
		||||
    ElTabs: typeof import('element-plus/es')['ElTabs']
 | 
			
		||||
    ElTag: typeof import('element-plus/es')['ElTag']
 | 
			
		||||
    ElUpload: typeof import('element-plus/es')['ElUpload']
 | 
			
		||||
    Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default']
 | 
			
		||||
    Pagination: typeof import('./src/components/Pagination/index.vue')['default']
 | 
			
		||||
 | 
			
		||||
@ -65,7 +65,7 @@
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  color: var(--color-sdk-auxiliary-public);
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  z-index: 999999;
 | 
			
		||||
  z-index: 99;
 | 
			
		||||
  background: linear-gradient(0deg, var(--color-sdk-bg-gradual)), rgba(0, 0, 0, 0.6);
 | 
			
		||||
  border: 1.5px solid;
 | 
			
		||||
  border-image: linear-gradient(to bottom, var(--color-sdk-gradual)) 1;
 | 
			
		||||
@ -76,8 +76,6 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.YJ-custom-base-dialog * {
 | 
			
		||||
  margin: 0px;
 | 
			
		||||
  padding: 0px;
 | 
			
		||||
  box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -171,7 +169,7 @@
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.YJ-custom-base-dialog button:not(button[disabled="disabled"]):hover {
 | 
			
		||||
.YJ-custom-base-dialog button:not(button[disabled]):hover {
 | 
			
		||||
  border-color: rgba(var(--color-sdk-base-rgb), 1) !important;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
@ -3888,3 +3886,81 @@
 | 
			
		||||
      /* 移回顶部外 */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 22px;
 | 
			
		||||
  height: 10px;
 | 
			
		||||
  margin-right: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.line {
 | 
			
		||||
  border: 1px solid rgba(255, 255, 255, 1);
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  margin-top: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.dash-line {
 | 
			
		||||
  border: 1px dashed rgba(255, 255, 255, 1);
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  margin-top: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.light-line {
 | 
			
		||||
  border: 1px solid rgba(255, 255, 255, 1);
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  margin-top: 4px;
 | 
			
		||||
  box-shadow: 0 0 3px #fff
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.tail-line {
 | 
			
		||||
  background: url(../../img/arrow/tail.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.mult-tail-line {
 | 
			
		||||
  background: url(../../img/arrow/tail.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.flow-dash-line1 {
 | 
			
		||||
  border: 1px dashed rgba(255, 255, 255, 1);
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  margin-top: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.flow-dash-line2 {
 | 
			
		||||
  border: 1px dashed rgba(255, 255, 255, 1);
 | 
			
		||||
  height: 0px;
 | 
			
		||||
  margin-top: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line1 {
 | 
			
		||||
  background: url(../../img/arrow/1.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line2 {
 | 
			
		||||
  background: url(../../img/arrow/2.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line3 {
 | 
			
		||||
  background: url(../../img/arrow/3.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line4 {
 | 
			
		||||
  background: url(../../img/arrow/4.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line5 {
 | 
			
		||||
  background: url(../../img/arrow/5.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yj-custom-icon.pic-line6 {
 | 
			
		||||
  background: url(../../img/arrow/6.png) 100% 100% no-repeat;
 | 
			
		||||
  background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ window.newFuzzySearch = function(
 | 
			
		||||
    let notSearchTypeNodesIds = [];
 | 
			
		||||
    if (notSearchType.length) {
 | 
			
		||||
      allNodes.forEach((allNodeItem) => {
 | 
			
		||||
        if (notSearchType.includes(allNodeItem.source_type)) {
 | 
			
		||||
        if (notSearchType.includes(allNodeItem.sourceType)) {
 | 
			
		||||
          notSearchTypeNodesIds.push(allNodeItem[idKey]);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
@ -81,19 +81,19 @@ window.newFuzzySearch = function(
 | 
			
		||||
    hideAllNode(allNodes);
 | 
			
		||||
    nodeChildren.forEach((item) => {
 | 
			
		||||
      if (item.oldname) {
 | 
			
		||||
        item.source_name = item.oldname;
 | 
			
		||||
        item.sourceName = item.oldname;
 | 
			
		||||
        zTreeObj.updateNode(item);
 | 
			
		||||
      }
 | 
			
		||||
      if (contrast) {
 | 
			
		||||
        if ((item.source_name || "").indexOf(contrast) > -1) {
 | 
			
		||||
          console.log("source_name包含关键字");
 | 
			
		||||
        if ((item.sourceName || "").indexOf(contrast) > -1) {
 | 
			
		||||
          console.log("sourceName包含关键字");
 | 
			
		||||
          console.log(item);
 | 
			
		||||
          console.log(item.source_name);
 | 
			
		||||
          console.log(item.sourceName);
 | 
			
		||||
 | 
			
		||||
          item.oldname = item.source_name;
 | 
			
		||||
          item.oldname = item.sourceName;
 | 
			
		||||
          item.highlight = true;
 | 
			
		||||
          let F = new RegExp(contrast, "gi");
 | 
			
		||||
          item.source_name = item.oldname.replace(F, function(h) {
 | 
			
		||||
          item.sourceName = item.oldname.replace(F, function(h) {
 | 
			
		||||
            let str =
 | 
			
		||||
              '<span style="color: whitesmoke;background-color: darkred;">' +
 | 
			
		||||
              h +
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								src/renderer/src/api/gisApi.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/renderer/src/api/gisApi.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
import request from '@/axios/request'
 | 
			
		||||
 | 
			
		||||
export const GisApi = {
 | 
			
		||||
  // 查询活动分页
 | 
			
		||||
  linkFile: async (data: any) => {
 | 
			
		||||
    return await request.post({
 | 
			
		||||
      url: `/fileInfo/upload`,
 | 
			
		||||
      data
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -5,7 +5,6 @@ export const TreeApi = {
 | 
			
		||||
  getTreeList: async () => {
 | 
			
		||||
    return await request.get({
 | 
			
		||||
      url: `/source/list`
 | 
			
		||||
      // url: `/yjearth4/api/v1/source/list`
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  // 新增其他资源  /source/addOtherSource
 | 
			
		||||
@ -19,9 +18,26 @@ export const TreeApi = {
 | 
			
		||||
  //新增节点
 | 
			
		||||
  addDirectory: async (data: any) => {
 | 
			
		||||
    return await request.post({
 | 
			
		||||
      url: `/yjearth4/api/v1/directory/add`,
 | 
			
		||||
      url: `/source/addOtherSource`,
 | 
			
		||||
      data
 | 
			
		||||
    })
 | 
			
		||||
    }).then((res) => {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '添加成功',
 | 
			
		||||
        type: 'success'
 | 
			
		||||
      })
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  // 更新节点信息
 | 
			
		||||
  updateDirectoryInfo: async (data: any) => {
 | 
			
		||||
    return await request.post({
 | 
			
		||||
      url: `/source/update`,
 | 
			
		||||
      data
 | 
			
		||||
    }).then((res) => {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '操作成功',
 | 
			
		||||
        type: 'success'
 | 
			
		||||
      })
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  //删除节点
 | 
			
		||||
  removeDirectory: async (data: any) => {
 | 
			
		||||
 | 
			
		||||
@ -293,7 +293,6 @@ img {
 | 
			
		||||
  background-color: rgba(0, 0, 0, 0.5) !important;
 | 
			
		||||
  border: none !important; /* 去除边框 */
 | 
			
		||||
  box-shadow: none !important; /* 去除阴影 */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.el-select-dropdown__item {
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="YJ-custom-base-dialog" ref="baseDialog" :id="id" :style="{
 | 
			
		||||
  <div class="YJ-custom-base-dialog" :class="className" ref="baseDialog" :id="id" :style="{
 | 
			
		||||
      width: width,
 | 
			
		||||
      height: height,
 | 
			
		||||
      top: top,
 | 
			
		||||
      left: left,
 | 
			
		||||
      position: fix ? 'fixed' : 'absolute'
 | 
			
		||||
    }" v-if="dialogVisible || first" v-show="dialogVisible">
 | 
			
		||||
    }" v-if="dialogVisible" v-show="dialogVisible">
 | 
			
		||||
    <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;">
 | 
			
		||||
@ -112,6 +110,7 @@ onMounted(() => {
 | 
			
		||||
const open = (data) => {
 | 
			
		||||
  if (!first.value) {
 | 
			
		||||
    first.value = true;
 | 
			
		||||
    dialogVisible.value = true;
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      moveDiv();
 | 
			
		||||
    });
 | 
			
		||||
@ -131,6 +130,7 @@ const close = () => {
 | 
			
		||||
    window.mapService?.removeAnimation();
 | 
			
		||||
  }
 | 
			
		||||
  callback.value && callback.value();
 | 
			
		||||
 | 
			
		||||
  props.closeCallback && props.closeCallback()
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -142,8 +142,8 @@ const moveDiv = () => {
 | 
			
		||||
 | 
			
		||||
  const oClickDiv = baseDialog.value;
 | 
			
		||||
  const oMoveDiv = titleBox.value;
 | 
			
		||||
 | 
			
		||||
  if (oClickDiv) {
 | 
			
		||||
    console.log(oMoveDiv)
 | 
			
		||||
    oMoveDiv.onmousedown = (e) => {
 | 
			
		||||
      // 获取对话框尺寸
 | 
			
		||||
      const oMoveDivHeight = baseDialog.value.offsetHeight;
 | 
			
		||||
@ -260,5 +260,25 @@ defineExpose({
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
 | 
			
		||||
.YJ-custom-base-dialog {
 | 
			
		||||
  ::v-deep .el-tabs {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    .el-tabs__item {
 | 
			
		||||
      padding: 0 8px;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
    }
 | 
			
		||||
    .el-tabs__item:nth-child(2) {
 | 
			
		||||
      padding: 0;
 | 
			
		||||
    }
 | 
			
		||||
    .el-tabs__item.is-active, .el-tabs__item:hover {
 | 
			
		||||
      color: #fff;
 | 
			
		||||
    }
 | 
			
		||||
    .el-tabs__active-bar {
 | 
			
		||||
      background-color: rgb(0, 255, 255);
 | 
			
		||||
    }
 | 
			
		||||
    .el-tabs__nav-wrap:after {
 | 
			
		||||
      background-color: rgba(204, 204, 204, 0.2)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,9 @@
 | 
			
		||||
          label-width="80px"
 | 
			
		||||
          @keyup.enter.native="submitForm(ruleForm)"
 | 
			
		||||
        >
 | 
			
		||||
          <el-form-item label="名称:" prop="source_name">
 | 
			
		||||
          <el-form-item label="名称:" prop="sourceName">
 | 
			
		||||
            <!-- @input="removeSpaces" -->
 | 
			
		||||
            <el-input v-model.trim="form.source_name" placeholder="图层文件夹"></el-input>
 | 
			
		||||
            <el-input v-model.trim="form.sourceName" placeholder="图层文件夹"></el-input>
 | 
			
		||||
          </el-form-item>
 | 
			
		||||
          <el-form-item>
 | 
			
		||||
            <div class="btnOption">
 | 
			
		||||
@ -42,14 +42,14 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
 | 
			
		||||
const { getKeyOfSelectedNode, getSelectedNode, cusAddNodes, getSameLevel } = useTreeNode()
 | 
			
		||||
const title = ref('添加文件夹')
 | 
			
		||||
let form: any = reactive({
 | 
			
		||||
  source_name: '图层'
 | 
			
		||||
  sourceName: '图层'
 | 
			
		||||
})
 | 
			
		||||
const ruleForm = ref()
 | 
			
		||||
const rules = reactive({
 | 
			
		||||
  source_name: [{ required: true, message: '请输入名称', trigger: 'blur' }]
 | 
			
		||||
  sourceName: [{ required: true, message: '请输入名称', trigger: 'blur' }]
 | 
			
		||||
})
 | 
			
		||||
const removeSpaces = (value: string) => {
 | 
			
		||||
  form.source_name = value.replace(/\s/g, '')
 | 
			
		||||
  form.sourceName = value.replace(/\s/g, '')
 | 
			
		||||
}
 | 
			
		||||
const close = () => {
 | 
			
		||||
  $changeComponentPop('.adddirectory', false)
 | 
			
		||||
@ -65,11 +65,11 @@ const submitForm = async (formEl: FormInstance | undefined) => {
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const add = throttle(async () => {
 | 
			
		||||
  let p_id = getKeyOfSelectedNode(window.treeObj, 'source_id')
 | 
			
		||||
  let parentId = getKeyOfSelectedNode(window.treeObj, 'id')
 | 
			
		||||
  let fnone = getSelectedNode(window.treeObj)
 | 
			
		||||
  const res = await TreeApi.addDirectory({
 | 
			
		||||
    source_name: form.source_name,
 | 
			
		||||
    p_id
 | 
			
		||||
    sourceName: form.sourceName,
 | 
			
		||||
    parentId
 | 
			
		||||
  })
 | 
			
		||||
  if (res.code == 0) {
 | 
			
		||||
    const node = {
 | 
			
		||||
@ -99,9 +99,9 @@ const add = throttle(async () => {
 | 
			
		||||
const updateTree = async (newNode: any) => {
 | 
			
		||||
  const list = newNode.map((item: any) => {
 | 
			
		||||
    return {
 | 
			
		||||
      source_id: item.source_id,
 | 
			
		||||
      id: item.id,
 | 
			
		||||
      tree_index: item.tree_index,
 | 
			
		||||
      p_id: item.p_id
 | 
			
		||||
      parentId: item.parentId
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  console.log(list)
 | 
			
		||||
@ -123,7 +123,7 @@ const updateTree = async (newNode: any) => {
 | 
			
		||||
 | 
			
		||||
const cancel = () => {
 | 
			
		||||
  $changeComponentPop('.adddirectory', false)
 | 
			
		||||
  form.source_name = '图层'
 | 
			
		||||
  form.sourceName = '图层'
 | 
			
		||||
  ruleForm.value?.resetFields()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,11 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="bottomMenuBox zIndex9">
 | 
			
		||||
    <div class="animate__animated bottomMenu">
 | 
			
		||||
      <div
 | 
			
		||||
        class="bottom_box"
 | 
			
		||||
        v-for="(item, i) of bottomMenuList"
 | 
			
		||||
        :key="i"
 | 
			
		||||
        :title="t('bottomMenu.' + item.source_type)"
 | 
			
		||||
        @click="addMarker(item)"
 | 
			
		||||
      >
 | 
			
		||||
        <svg-icon :name="item.source_type" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon>
 | 
			
		||||
      <div 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>
 | 
			
		||||
        <div class="span">
 | 
			
		||||
          {{ t('bottomMenu.' + item.source_type) }}
 | 
			
		||||
          {{ t('bottomMenu.' + item.sourceType) }}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@ -21,6 +16,8 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { useI18n } from 'vue-i18n'
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import { TreeApi } from '@/api/tree'
 | 
			
		||||
import { initMapData } from '../tree/initMapData'
 | 
			
		||||
const { t } = useI18n()
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
 | 
			
		||||
@ -40,76 +37,178 @@ onMounted(() => {
 | 
			
		||||
})
 | 
			
		||||
const bottomMenuList = ref([
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '贴地文字',
 | 
			
		||||
    sourceName: '贴地文字',
 | 
			
		||||
    key: 'groundText',
 | 
			
		||||
    source_type: 'groundText',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'groundText',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      eventBus.emit("openDialog", 'groundText');
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '立体文字',
 | 
			
		||||
    sourceName: '立体文字',
 | 
			
		||||
    key: 'standText',
 | 
			
		||||
    source_type: 'standText',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'standText',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      eventBus.emit("openDialog", 'standText');
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '点标注',
 | 
			
		||||
    sourceName: '点标注',
 | 
			
		||||
    key: 'DrawPoint',
 | 
			
		||||
    source_type: 'point',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'point',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      let Draw = new YJ.Draw.DrawPoint(window.earth)
 | 
			
		||||
      Draw.start(async (a, position) => {
 | 
			
		||||
        if (!position) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        let id = new YJ.Tools().randomString()
 | 
			
		||||
        let name = '点标注'
 | 
			
		||||
        let options: any = await initMapData('point', {
 | 
			
		||||
          id: id,
 | 
			
		||||
          name: name,
 | 
			
		||||
          position: position,
 | 
			
		||||
        })
 | 
			
		||||
        let selectedNodes = window.treeObj.getSelectedNodes()
 | 
			
		||||
        delete options.host
 | 
			
		||||
        let params = {
 | 
			
		||||
          "id": id,
 | 
			
		||||
          "sourceName": name,
 | 
			
		||||
          "sourceType": "point",
 | 
			
		||||
          "parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
 | 
			
		||||
          // "treeIndex": 0,
 | 
			
		||||
          "params": options
 | 
			
		||||
        }
 | 
			
		||||
        TreeApi.addDirectory(params)
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '线标注',
 | 
			
		||||
    sourceName: '线标注',
 | 
			
		||||
    key: 'DrawPolyline',
 | 
			
		||||
    source_type: 'line',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'line',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      // eventBus.emit("openDialog", 'line', 'aaa');
 | 
			
		||||
      // return
 | 
			
		||||
      let Draw = new YJ.Draw.DrawPolyline(window.earth)
 | 
			
		||||
      Draw.start(async (a, positions) => {
 | 
			
		||||
        if (!positions || positions.length < 2) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        let id = new YJ.Tools().randomString()
 | 
			
		||||
        let name = '线标注'
 | 
			
		||||
        let options: any = await initMapData('line', {
 | 
			
		||||
          id: id,
 | 
			
		||||
          name: name,
 | 
			
		||||
          positions: positions,
 | 
			
		||||
        })
 | 
			
		||||
        let selectedNodes = window.treeObj.getSelectedNodes()
 | 
			
		||||
        let params = {
 | 
			
		||||
          "id": id,
 | 
			
		||||
          "sourceName": name,
 | 
			
		||||
          "sourceType": "line",
 | 
			
		||||
          "parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
 | 
			
		||||
          // "treeIndex": 0,
 | 
			
		||||
          "params": options
 | 
			
		||||
        }
 | 
			
		||||
        TreeApi.addDirectory(params)
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '曲线标注',
 | 
			
		||||
    sourceName: '曲线标注',
 | 
			
		||||
    key: 'DrawPolyline',
 | 
			
		||||
    source_type: 'curve',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'curve',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      let Draw = new YJ.Draw.DrawPolyline(window.earth, { curve: true })
 | 
			
		||||
      Draw.start(async (a, positions) => {
 | 
			
		||||
        if (!positions || positions.length < 2) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        let id = new YJ.Tools().randomString()
 | 
			
		||||
        let name = '曲线标注'
 | 
			
		||||
        let options: any = await initMapData('curve', {
 | 
			
		||||
          id: id,
 | 
			
		||||
          name: name,
 | 
			
		||||
          positions: positions,
 | 
			
		||||
        })
 | 
			
		||||
        
 | 
			
		||||
        let selectedNodes = window.treeObj.getSelectedNodes()
 | 
			
		||||
        let params = {
 | 
			
		||||
          "id": id,
 | 
			
		||||
          "sourceName": name,
 | 
			
		||||
          "sourceType": "curve",
 | 
			
		||||
          "parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
 | 
			
		||||
          // "treeIndex": 0,
 | 
			
		||||
          "params": options
 | 
			
		||||
        }
 | 
			
		||||
        TreeApi.addDirectory(params)
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '面标注',
 | 
			
		||||
    sourceName: '面标注',
 | 
			
		||||
    key: 'DrawPolygon',
 | 
			
		||||
    source_type: 'panel',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
    sourceType: 'panel',
 | 
			
		||||
    className: 'public',
 | 
			
		||||
    fun: () => {
 | 
			
		||||
      let Draw = new YJ.Draw.DrawPolygon(window.earth)
 | 
			
		||||
      Draw.start((a, positions) => {
 | 
			
		||||
        if (!positions || positions.length < 3) {
 | 
			
		||||
          ElMessage({
 | 
			
		||||
            message: '至少需要绘制三个坐标!',
 | 
			
		||||
            type: 'warning'
 | 
			
		||||
          })
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        let PolygonObject = new YJ.Obj.PolygonObject(window.earth, { id: new YJ.Tools().randomString(), positions: positions })
 | 
			
		||||
        PolygonObject.onClick = (a, b, c) => {
 | 
			
		||||
          console.log(a, b, c)
 | 
			
		||||
        }
 | 
			
		||||
        eventBus.emit("openDialog", 'panel', PolygonObject.options.id);
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '圆标注',
 | 
			
		||||
    sourceName: '圆标注',
 | 
			
		||||
    key: 'DrawCircle',
 | 
			
		||||
    source_type: 'circle',
 | 
			
		||||
    sourceType: 'circle',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '矩形',
 | 
			
		||||
    sourceName: '矩形',
 | 
			
		||||
    key: 'DrawRect',
 | 
			
		||||
    source_type: 'rectangle',
 | 
			
		||||
    sourceType: 'rectangle',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '集结地',
 | 
			
		||||
    sourceName: '集结地',
 | 
			
		||||
    key: 'DrawAssemble',
 | 
			
		||||
    source_type: 'rendezvous',
 | 
			
		||||
    sourceType: 'rendezvous',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '箭头',
 | 
			
		||||
    sourceName: '箭头',
 | 
			
		||||
    key: 'DrawAttackArrow',
 | 
			
		||||
    source_type: 'attackArrow',
 | 
			
		||||
    sourceType: 'attackArrow',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    source_name: '钳形箭头',
 | 
			
		||||
    sourceName: '钳形箭头',
 | 
			
		||||
    key: 'DrawPincerArrow',
 | 
			
		||||
    source_type: 'pincerArrow',
 | 
			
		||||
    sourceType: 'pincerArrow',
 | 
			
		||||
    className: 'public'
 | 
			
		||||
  }
 | 
			
		||||
  // {
 | 
			
		||||
  //   source_name: "锁定",
 | 
			
		||||
  //   sourceName: "锁定",
 | 
			
		||||
  //   key: "lock",
 | 
			
		||||
  //   source_type: "unLock",
 | 
			
		||||
  //   sourceType: "unLock",
 | 
			
		||||
  //   className: "public",
 | 
			
		||||
  // },
 | 
			
		||||
])
 | 
			
		||||
@ -161,34 +260,7 @@ const fold = () => {
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
const addMarker = (item: any) => {
 | 
			
		||||
  switch (item.source_type) {
 | 
			
		||||
    case 'groundText':
 | 
			
		||||
      eventBus.emit("openDialog");
 | 
			
		||||
      break;
 | 
			
		||||
    case 'standText':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'point':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'line':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'curve':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'panel':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'circle':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'rectangle':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'rendezvous':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'attackArrow':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'pincerArrow':
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  item.fun()
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -231,7 +303,7 @@ const addMarker = (item: any) => {
 | 
			
		||||
      transform: scale(0.8);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    > .span {
 | 
			
		||||
    >.span {
 | 
			
		||||
      color: #fff;
 | 
			
		||||
      font-family: 黑体;
 | 
			
		||||
      font-size: 1rem;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,60 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="贴地文字" left="180px" top="100px">
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <textarea style="height: 76px; width: 270px;" v-model="text"></textarea>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="confirm">确定</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'
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const text = ref("")
 | 
			
		||||
eventBus.on("openStandTextAdd", () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
});
 | 
			
		||||
const open = () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
}
 | 
			
		||||
const confirm = () => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
  let name = text.value
 | 
			
		||||
  text.value = ''
 | 
			
		||||
  let Draw = new YJ.Draw.DrawPolyline(window.earth, { number: 2 })
 | 
			
		||||
  Draw.start(async (a, positions) => {
 | 
			
		||||
    if(!positions || positions.length < 2) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    let id = new YJ.Tools().randomString()
 | 
			
		||||
    let options: any = await initMapData('groundText', {
 | 
			
		||||
      id: id,
 | 
			
		||||
      name: name,
 | 
			
		||||
      positions: positions,
 | 
			
		||||
    })
 | 
			
		||||
    let selectedNodes = window.treeObj.getSelectedNodes()
 | 
			
		||||
    let params = {
 | 
			
		||||
      "id": id,
 | 
			
		||||
      "sourceName": name,
 | 
			
		||||
      "sourceType": "groundText",
 | 
			
		||||
      "parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
 | 
			
		||||
      // "treeIndex": 0,
 | 
			
		||||
      "params": options
 | 
			
		||||
    }
 | 
			
		||||
    TreeApi.addDirectory(params)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@ -0,0 +1,60 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="立体文字" left="180px" top="100px">
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <textarea style="height: 76px; width: 270px;" v-model="text"></textarea>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button @click="confirm">确定</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'
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const text = ref("")
 | 
			
		||||
eventBus.on("openStandTextAdd", () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
});
 | 
			
		||||
const open = () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
}
 | 
			
		||||
const confirm = () => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
  let name = text.value
 | 
			
		||||
  text.value = ''
 | 
			
		||||
  let Draw = new YJ.Draw.DrawPolyline(window.earth)
 | 
			
		||||
  Draw.start(async (a, positions) => {
 | 
			
		||||
    if (!positions || positions.length < 2) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    let id = new YJ.Tools().randomString()
 | 
			
		||||
    let options: any = await initMapData('standText', {
 | 
			
		||||
      id: id,
 | 
			
		||||
      name: name,
 | 
			
		||||
      positions: positions,
 | 
			
		||||
    })
 | 
			
		||||
    let selectedNodes = window.treeObj.getSelectedNodes()
 | 
			
		||||
    let params = {
 | 
			
		||||
      "id": id,
 | 
			
		||||
      "sourceName": name,
 | 
			
		||||
      "sourceType": "standText",
 | 
			
		||||
      "parentId": (selectedNodes && selectedNodes[selectedNodes.length - 1]) ? selectedNodes[selectedNodes.length - 1].id : undefined,
 | 
			
		||||
      // "treeIndex": 0,
 | 
			
		||||
      "params": options
 | 
			
		||||
    }
 | 
			
		||||
    TreeApi.addDirectory(params)
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
							
								
								
									
										320
									
								
								src/renderer/src/views/components/propertyBox/attribute.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								src/renderer/src/views/components/propertyBox/attribute.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,320 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="attribute">
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col attribute-select-box">
 | 
			
		||||
        <span class="label" style="line-height: 32px;">内容类型</span>
 | 
			
		||||
        <el-select 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-select>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-richText" v-show="attributeType === 'richText'">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
          <span class="label">编辑内容</span>
 | 
			
		||||
          <button @click="openRichTextEditor">打开文本编辑器</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row attribute-content attribute-content-link" v-show="attributeType === 'link'">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">添加链接</span>
 | 
			
		||||
        <div style="flex: 1;position: relative;">
 | 
			
		||||
          <input class="input link_add" type="text" v-model="addlinkInput">
 | 
			
		||||
          <i class="link_add_btn" @click="_addLink"></i>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-link" v-show="attributeType === 'link'">
 | 
			
		||||
      <div class="table">
 | 
			
		||||
        <div class="table-head">
 | 
			
		||||
          <div class="tr">
 | 
			
		||||
            <div class="th">名称</div>
 | 
			
		||||
            <div class="th">链接</div>
 | 
			
		||||
            <div class="th">操作</div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table-body" v-if="attribute.link.content && attribute.link.content.length > 0">
 | 
			
		||||
          <div class="tr" v-for="(item, index) in attribute.link.content">
 | 
			
		||||
            <div class="td" v-if="linkEditActive.index === index">
 | 
			
		||||
              <input class="input" type="text" v-model="linkEditActive.name">
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="td" v-else>{{ item.name }}</div>
 | 
			
		||||
            <div class="td" v-if="linkEditActive.index === index">
 | 
			
		||||
              <textarea class="input link-edit" type="text" v-model="linkEditActive.url"></textarea>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="td" v-else>{{ item.url }}</div>
 | 
			
		||||
            <div class="td" v-if="linkEditActive.index === index">
 | 
			
		||||
              <button @click="linkConfirmEdit(index)">确认</button>
 | 
			
		||||
              <button @click="linkCancelEdit">取消</button>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="td" v-else>
 | 
			
		||||
              <button @click="linkEdit(index, item)">编辑</button>
 | 
			
		||||
              <button @click="linkDelete(index)">删除</button>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table-empty" v-else>
 | 
			
		||||
          <div class="empty-img"></div>
 | 
			
		||||
          <p>暂无数据</p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-camera" v-show="attributeType === 'camera'">
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
          <span class="label">编辑内容</span>
 | 
			
		||||
          <input class="input" type="text" @model="cameraName" style="width: 100px;">
 | 
			
		||||
          <button class="select btn" @click="cameraSelect">搜索</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div>
 | 
			
		||||
        <div class="table camera-table">
 | 
			
		||||
          <div class="table-head">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <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: 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">密码</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-body" style="display:none;">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <div class="td">
 | 
			
		||||
                <input type="checkbox" value="2">
 | 
			
		||||
                <span>绑定</span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="td">设备名称</div>
 | 
			
		||||
              <div class="td">设备类型</div>
 | 
			
		||||
              <div class="td">设备IP</div>
 | 
			
		||||
              <div class="td">设备端口</div>
 | 
			
		||||
              <div class="td">用户名</div>
 | 
			
		||||
              <div class="td">密码</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-empty">
 | 
			
		||||
            <div class="empty-img"></div>
 | 
			
		||||
            <p>暂无数据</p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="" row>
 | 
			
		||||
        <ul class="pagination"></ul>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-isc" v-show="attributeType === 'isc'">
 | 
			
		||||
      <!-- <div class="row">
 | 
			
		||||
                    <div class="col">
 | 
			
		||||
                        <span class="label">编辑内容</span>
 | 
			
		||||
                        <input class="input" type="text" @model="ISCName" style="width: 100px;">
 | 
			
		||||
                        <button class="select btn" @click="ISCSelect">搜索</button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div> -->
 | 
			
		||||
      <div>
 | 
			
		||||
        <div class="table isc-table">
 | 
			
		||||
          <div class="table-head">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <div class="th" style="width: 74px; flex: 0 74px;min-width: 74px;">操作</div>
 | 
			
		||||
              <div class="th">设备名称</div>
 | 
			
		||||
              <div class="th" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-body" style="display:none;">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <div class="td">
 | 
			
		||||
                <input type="checkbox" value="2">
 | 
			
		||||
                <span>绑定</span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="td">设备名称</div>
 | 
			
		||||
              <div class="td" style="width: 180px; flex: 0 180px; min-width: 180px;">设备状态</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-empty">
 | 
			
		||||
            <div class="empty-img"></div>
 | 
			
		||||
            <p>暂无数据</p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="" row>
 | 
			
		||||
        <ul class="pagination"></ul>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row attribute-content attribute-content-vr" v-show="attributeType === 'vr'">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">添加链接</span>
 | 
			
		||||
        <div style="flex: 1;position: relative;">
 | 
			
		||||
          <input class="input vr_add" type="text">
 | 
			
		||||
          <i class="vr_add_btn" @click="_addRr"></i>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-vr" v-show="attributeType === 'vr'">
 | 
			
		||||
      <div class="table">
 | 
			
		||||
        <div class="table-head">
 | 
			
		||||
          <div class="tr">
 | 
			
		||||
            <div class="th">名称</div>
 | 
			
		||||
            <div class="th">链接</div>
 | 
			
		||||
            <div class="th">操作</div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table-body">
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table-empty">
 | 
			
		||||
          <div class="empty-img"></div>
 | 
			
		||||
          <p>暂无数据</p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="attribute-content attribute-content-goods" v-show="attributeType === 'goods'">
 | 
			
		||||
      <div>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <span class="label">编辑内容</span>
 | 
			
		||||
            <input class="input goods-select-input" type="text" style="width: 180px;margin-right: 10px;">
 | 
			
		||||
            <button class="select btn" @click="goodsFilter">搜索</button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table goods-table">
 | 
			
		||||
          <div class="table-head">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <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">数量</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-body" style="display:none;">
 | 
			
		||||
            <div class="tr">
 | 
			
		||||
              <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">数量</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="table-empty">
 | 
			
		||||
            <div class="empty-img"></div>
 | 
			
		||||
            <p>暂无数据</p>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const attributeType = ref('richText')
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  entityOptions: {
 | 
			
		||||
    type: Object,
 | 
			
		||||
    default: {}
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const attribute = ref(props.entityOptions.options.attribute)
 | 
			
		||||
const richTextContent = ref(props.entityOptions.options.richTextContent)
 | 
			
		||||
 | 
			
		||||
const attributeSelect = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '富文本',
 | 
			
		||||
    value: '富文本',
 | 
			
		||||
    key: 'richText'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '链接',
 | 
			
		||||
    value: '链接',
 | 
			
		||||
    key: 'link'
 | 
			
		||||
  },
 | 
			
		||||
  // {
 | 
			
		||||
  //   name: 'IP摄像头',
 | 
			
		||||
  //   value: 'IP摄像头',
 | 
			
		||||
  //   key: 'camera'
 | 
			
		||||
  // },
 | 
			
		||||
  // {
 | 
			
		||||
  //   name: 'ISC摄像头',
 | 
			
		||||
  //   value: 'ISC摄像头',
 | 
			
		||||
  //   key: 'isc'
 | 
			
		||||
  // },
 | 
			
		||||
  // {
 | 
			
		||||
  //   name: '传感器',
 | 
			
		||||
  //   value: '传感器',
 | 
			
		||||
  //   key: 'sensor'
 | 
			
		||||
  // },
 | 
			
		||||
  // {
 | 
			
		||||
  //   name: '全景图',
 | 
			
		||||
  //   value: '全景图',
 | 
			
		||||
  //   key: 'vr'
 | 
			
		||||
  // },
 | 
			
		||||
  // {
 | 
			
		||||
  //   name: '物资',
 | 
			
		||||
  //   value: '物资',
 | 
			
		||||
  //   key: 'goods'
 | 
			
		||||
  // },
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const cameraName = ref('')
 | 
			
		||||
const addlinkInput = ref('')
 | 
			
		||||
const linkEditActive = ref({})
 | 
			
		||||
 | 
			
		||||
const openRichTextEditor = () => {
 | 
			
		||||
  eventBus.emit('openRichText', props.entityOptions.name, richTextContent.value, (val) => {
 | 
			
		||||
    richTextContent.value = val
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const _addLink = () => {
 | 
			
		||||
  if (addlinkInput.value) {
 | 
			
		||||
    let link = {
 | 
			
		||||
      name: '链接',
 | 
			
		||||
      url: addlinkInput.value
 | 
			
		||||
    }
 | 
			
		||||
    attribute.value.link.content.push(link)
 | 
			
		||||
    addlinkInput.value = ''
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    document.getElementById('fileInputlink')?.click();
 | 
			
		||||
    eventBus.emit('defineClickAddLinkCb', (list) => {
 | 
			
		||||
      list.forEach((item) => {
 | 
			
		||||
        attribute.value.link.content.push({
 | 
			
		||||
          name: "链接",
 | 
			
		||||
          url: item.previewUrl,
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const linkEdit = (index, item) => {
 | 
			
		||||
  let active = {
 | 
			
		||||
    index: index,
 | 
			
		||||
    name: item.name,
 | 
			
		||||
    url: item.url
 | 
			
		||||
  }
 | 
			
		||||
  linkEditActive.value = active
 | 
			
		||||
}
 | 
			
		||||
const linkDelete = (index) => {
 | 
			
		||||
  attribute.value.link.content.splice(index, 1)
 | 
			
		||||
}
 | 
			
		||||
const linkConfirmEdit = (index) => {
 | 
			
		||||
  attribute.value.link.content[index] = linkEditActive.value
 | 
			
		||||
  linkEditActive.value = {}
 | 
			
		||||
}
 | 
			
		||||
const linkCancelEdit = () => {
 | 
			
		||||
  linkEditActive.value = {}
 | 
			
		||||
}
 | 
			
		||||
const cameraSelect = () => { }
 | 
			
		||||
const _addRr = () => { }
 | 
			
		||||
const goodsFilter = () => { }
 | 
			
		||||
const attributeChange = () => { }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
@ -0,0 +1,649 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="点标注" left="180px" top="100px" :className="'billboard-object'"
 | 
			
		||||
    :closeCallback="closeCallback">
 | 
			
		||||
    <template #content>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <span class="label" style="flex: unset;">名称</span>
 | 
			
		||||
            <input class="input" type="text" v-model="entityOptions.name" @change="changeName">
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col">
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div style="width: 46%;">
 | 
			
		||||
            <div class="row">
 | 
			
		||||
              <p class="lable-left-line">WGS84坐标</p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row" style="margin-bottom: 5px;">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">经度</span>
 | 
			
		||||
                <input class="input" type="number" title="" min="-180" max="180" v-model="entityOptions.lng"
 | 
			
		||||
                  @change="changLng">
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row" style="margin-bottom: 5px;">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">纬度</span>
 | 
			
		||||
                <input class="input" type="number" title="" min="-90" max="90" v-model="entityOptions.lat"
 | 
			
		||||
                  @change="changLat">
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">海拔高度</span>
 | 
			
		||||
                <div class="input-number input-number-unit-1 alt-box"
 | 
			
		||||
                  :class="{ 'disabled': heightMode == 2 || heightMode === 3 }">
 | 
			
		||||
                  <input class="input" type="number" title="" min="-9999999" max="999999999" v-model="entityOptions.alt"
 | 
			
		||||
                    @change="changAlt">
 | 
			
		||||
                  <span class="unit">m</span>
 | 
			
		||||
                  <span class="arrow"></span>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div style="width: 50%;">
 | 
			
		||||
            <div class="row coordinate-select-box">
 | 
			
		||||
              <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-option v-for="item in epsg_map" :key="item.epsg" :label="item.name" :value="item.epsg">
 | 
			
		||||
                  </el-option>
 | 
			
		||||
                </el-select>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row" style="margin-bottom: 5px;">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">X轴:</span>
 | 
			
		||||
                <input style="border: none;background: none;" class="input convert-x" readonly="readonly" v-model="x">
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row" style="margin-bottom: 5px;">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">Y轴:</span>
 | 
			
		||||
                <input style="border: none;background: none;" class="input convert-y" readonly="readonly" v-model="y">
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
              <div class="col">
 | 
			
		||||
                <span class="label">Z轴:</span>
 | 
			
		||||
                <input style="border: none;background: none;" class="input convert-z" readonly="readonly" v-model="z">
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <div class="col" style="flex: 0 0 120px;">
 | 
			
		||||
            <span class="label">视野缩放</span>
 | 
			
		||||
            <input class="btn-switch" type="checkbox" v-model="entityOptions.scaleByDistance">
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <span class="label">最近距离</span>
 | 
			
		||||
            <div class="input-number input-number-unit-1">
 | 
			
		||||
              <input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.near">
 | 
			
		||||
              <span class="unit">m</span>
 | 
			
		||||
              <span class="arrow"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col">
 | 
			
		||||
            <span class="label">最远距离</span>
 | 
			
		||||
            <div class="input-number input-number-unit-1">
 | 
			
		||||
              <input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.far">
 | 
			
		||||
              <span class="unit">m</span>
 | 
			
		||||
              <span class="arrow"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <el-tabs v-model="activeName" @tab-click="handleClick">
 | 
			
		||||
            <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 height-box" v-show="heightMode == 0 || heightMode == 1">
 | 
			
		||||
                  <span class="label" style="flex: 0 0 56px;">高度</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1">
 | 
			
		||||
                    <input class="input height" type="number" title="" min="-9999999" max="999999999" v-model="height"
 | 
			
		||||
                      @change="changHeight">
 | 
			
		||||
                    <span class="unit">m</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;"
 | 
			
		||||
                    @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 class="col">
 | 
			
		||||
                  <div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;"
 | 
			
		||||
                    @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 class="col">
 | 
			
		||||
                  <div class="YJ-custom-checkbox-box" style="display: flex;align-items: center;cursor: pointer;"
 | 
			
		||||
                    @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 class="col">
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div style="flex: 1;">
 | 
			
		||||
                  <div class="proj-input-box" v-show="format1">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                      <div class="col">
 | 
			
		||||
                        <span style="flex: 0 0 40px;">经度</span>
 | 
			
		||||
                        <input class="input lng" readonly="readonly" :value="entityOptions.lng">
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="col">
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                      <div class="col">
 | 
			
		||||
                        <span style="flex: 0 0 40px;">纬度</span>
 | 
			
		||||
                        <input class="input lat" readonly="readonly" :value="entityOptions.lat">
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="col">
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="proj-input-box" style="width: 56%;" v-show="format2">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                      <div class="col" style="flex-direction: column;">
 | 
			
		||||
                        <div class="row" style="margin-bottom: 15px;">
 | 
			
		||||
                          <span style="flex: 0 0 40px;">经度</span>
 | 
			
		||||
                          <input class="input lng-dm-d" style="flex: 1;" readonly="readonly" :value="lngDmD">
 | 
			
		||||
                          <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">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
 | 
			
		||||
                          <span class="top-line"></span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row">
 | 
			
		||||
                          <span style="flex: 0 0 40px;">纬度</span>
 | 
			
		||||
                          <input class="input lat-dm-d" style="flex: 1;" readonly="readonly" :value="latDmD">
 | 
			
		||||
                          <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">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">分</span>
 | 
			
		||||
                          <span class="bottom-line"></span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="proj-input-box" style="width: 70%;" v-show="format3">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                      <div class="col" style="flex-direction: column;">
 | 
			
		||||
                        <div class="row" style="margin-bottom: 15px;">
 | 
			
		||||
                          <span style="flex: 0 0 40px;">经度</span>
 | 
			
		||||
                          <input class="input lng-dms-d" style="flex: 1;" readonly="readonly" :value="lngDmsD">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
 | 
			
		||||
                          <input class="input lng-dms-m" style="flex: 1;" readonly="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="readonly" :value="lngDmsS">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">秒</span>
 | 
			
		||||
                          <span class="top-line"></span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="row">
 | 
			
		||||
                          <span style="flex: 0 0 40px;">纬度</span>
 | 
			
		||||
                          <input class="input lat-dms-d" style="flex: 1;" readonly="readonly" :value="latDmsD">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">度</span>
 | 
			
		||||
                          <input class="input lat-dms-m" style="flex: 1;" readonly="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="readonly" :value="latDmsS">
 | 
			
		||||
                          <span class="label" style="flex: 0 0 14px;margin: 0 10px;">秒</span>
 | 
			
		||||
                          <span class="bottom-line"></span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane label="标注风格" name="3">
 | 
			
		||||
              <div>
 | 
			
		||||
                <h4>图标设置</h4>
 | 
			
		||||
                <div class="row" style="margin-bottom: 10px;">
 | 
			
		||||
                  <div class="col" style="flex: 0 0 80px;">
 | 
			
		||||
                    <span class="label" style="flex: none;">显隐</span>
 | 
			
		||||
                    <input class="btn-switch" type="checkbox" v-model="entityOptions.billboardShow">
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col" style="flex: 0 0 90px;">
 | 
			
		||||
                    <span class="label" style="flex: none;">图标</span>
 | 
			
		||||
                    <div class="image-box" @click="clickChangeImage">
 | 
			
		||||
                      <img class="image" :src="entityOptions.billboardImage" alt="">
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col" style="flex: 0 0 90px;">
 | 
			
		||||
                    <span class="label" style="flex: none;">默认图标</span>
 | 
			
		||||
                    <div class="image-box" @click="clickChangeDefaultImage">
 | 
			
		||||
                      <img class="image" :src="entityOptions.billboardDefaultImage" alt="">
 | 
			
		||||
                    </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.1" max="99"
 | 
			
		||||
                        v-model="entityOptions.billboardScale">
 | 
			
		||||
                      <span class="unit">倍</span>
 | 
			
		||||
                      <span class="arrow"></span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div>
 | 
			
		||||
                <h4>文字设置</h4>
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                  <div class="col" style="flex: 0 0 80px;">
 | 
			
		||||
                    <span class="label" style="flex: none;">显隐</span>
 | 
			
		||||
                    <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow">
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col font-select-box">
 | 
			
		||||
                    <span class="label" style="flex: none;">字体选择</span>
 | 
			
		||||
                    <el-select 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-select>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col">
 | 
			
		||||
                    <span class="label">文字大小</span>
 | 
			
		||||
                    <div class="input-number input-number-unit-2">
 | 
			
		||||
                      <input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize"
 | 
			
		||||
                        style="width: 70px;">
 | 
			
		||||
                      <span class="unit">px</span>
 | 
			
		||||
                      <span class="arrow"></span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col">
 | 
			
		||||
                    <span class="label">文字颜色</span>
 | 
			
		||||
                    <div class="labelColor" ref="labelColorRef"></div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
          </el-tabs>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <div style="position: absolute; left: 24px; display: flex;">
 | 
			
		||||
        <button @click="updateHeight"><svg class="icon-updateheigh">
 | 
			
		||||
            <use xlink:href="#yj-icon-updateheight"></use>
 | 
			
		||||
          </svg>更新高程</button>
 | 
			
		||||
        <button style="margin-left: 10px;" @click="translate">平移</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 { getFontList } from './fontSelect'
 | 
			
		||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
 | 
			
		||||
 | 
			
		||||
const { cusUpdateNode } = useTreeNode()
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
 | 
			
		||||
const epsg_map = ref([{
 | 
			
		||||
  "name": "WGS 84 / UTM zone 3N",
 | 
			
		||||
  "epsg": "EPSG:32603",
 | 
			
		||||
  "def": "+proj=utm +zone=3 +datum=WGS84 +units=m +no_defs"
 | 
			
		||||
}])
 | 
			
		||||
let array = []
 | 
			
		||||
for (const [key, value] of window.earth.proj.epsg_map) {
 | 
			
		||||
  let item = structuredClone(value)
 | 
			
		||||
  item.name = item.name + `(${item.epsg}})`
 | 
			
		||||
  array.push(item)
 | 
			
		||||
}
 | 
			
		||||
epsg_map.value = array
 | 
			
		||||
 | 
			
		||||
const format1 = ref(true)
 | 
			
		||||
const format2 = ref(false)
 | 
			
		||||
const format3 = ref(false)
 | 
			
		||||
const lngDmD = ref('')
 | 
			
		||||
const lngDmM = ref('')
 | 
			
		||||
const latDmD = ref('')
 | 
			
		||||
const latDmM = ref('')
 | 
			
		||||
const lngDmsD = ref('')
 | 
			
		||||
const lngDmsM = ref('')
 | 
			
		||||
const latDmsD = ref('')
 | 
			
		||||
const latDmsM = ref('')
 | 
			
		||||
const lngDmsS = ref('')
 | 
			
		||||
const latDmsS = ref('')
 | 
			
		||||
 | 
			
		||||
const fontList = ref(getFontList())
 | 
			
		||||
const height = ref(0)
 | 
			
		||||
const heightModeData = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '海拔高度',
 | 
			
		||||
    value: '海拔高度',
 | 
			
		||||
    key: 0
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '相对地表',
 | 
			
		||||
    value: '相对地表',
 | 
			
		||||
    key: 1
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '依附地表',
 | 
			
		||||
    value: '依附地表',
 | 
			
		||||
    key: 2
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '依附模型',
 | 
			
		||||
    value: '依附模型',
 | 
			
		||||
    key: 3
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
const activeName = ref('1')
 | 
			
		||||
const entityOptions = ref({});
 | 
			
		||||
const x = ref();
 | 
			
		||||
const y = ref();
 | 
			
		||||
const z = ref();
 | 
			
		||||
const coordinate = ref('EPSG:4326')
 | 
			
		||||
const heightMode = ref(0)
 | 
			
		||||
const labelColorRef = ref(null)
 | 
			
		||||
 | 
			
		||||
let originalOptions
 | 
			
		||||
let that
 | 
			
		||||
const open = async (id) => {
 | 
			
		||||
  that = window.earth.entityMap.get(id)
 | 
			
		||||
  originalOptions = structuredClone(that.options)
 | 
			
		||||
  entityOptions.value = that
 | 
			
		||||
  heightMode.value = entityOptions.value.heightMode
 | 
			
		||||
  projConvert()
 | 
			
		||||
  heightModeChange(heightMode.value)
 | 
			
		||||
  x.value = that.lng
 | 
			
		||||
  y.value = that.lat
 | 
			
		||||
  z.value = that.alt
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  let labelColorPicker = new YJColorPicker({
 | 
			
		||||
    el: labelColorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: entityOptions.value.labelColor,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      entityOptions.value.labelColor = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      entityOptions.value.labelColor = 'rgba(255,255,255,1)'
 | 
			
		||||
    } //点击清空按钮事件回调
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const closeCallback = () => {
 | 
			
		||||
  entityOptions.value.originalOptions = structuredClone(originalOptions)
 | 
			
		||||
  that.positionEditing = false
 | 
			
		||||
  that.reset()
 | 
			
		||||
  eventBus.emit("destroyComponent")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const changeName = (e) => {
 | 
			
		||||
  entityOptions.value.labelText = e.target.value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const coordinateChange = () => {
 | 
			
		||||
  let position = window.earth.proj.convert(
 | 
			
		||||
    [
 | 
			
		||||
      {
 | 
			
		||||
        x: entityOptions.value.lng,
 | 
			
		||||
        y: entityOptions.value.lat,
 | 
			
		||||
        z: entityOptions.value.alt
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    'EPSG:4326',
 | 
			
		||||
    coordinate.value
 | 
			
		||||
  ).points
 | 
			
		||||
  x.value = position[0].x
 | 
			
		||||
  y.value = position[0].y
 | 
			
		||||
  z.value = position[0].z
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const heightModeChange = (val) => {
 | 
			
		||||
  switch (val) {
 | 
			
		||||
    case 0:
 | 
			
		||||
    case '0':
 | 
			
		||||
      height.value = entityOptions.value.alt
 | 
			
		||||
      break
 | 
			
		||||
    case 1:
 | 
			
		||||
    case '1':
 | 
			
		||||
      if (window.earth.viewer.scene.terrainProvider.availability) {
 | 
			
		||||
        Cesium.sampleTerrainMostDetailed(
 | 
			
		||||
          window.earth.viewer.scene.terrainProvider,
 | 
			
		||||
          [
 | 
			
		||||
            Cesium.Cartographic.fromDegrees(
 | 
			
		||||
              entityOptions.value.lng,
 | 
			
		||||
              entityOptions.value.lat
 | 
			
		||||
            )
 | 
			
		||||
          ]
 | 
			
		||||
        ).then(position => {
 | 
			
		||||
          height.value = entityOptions.value.alt - Number(position[0].height.toFixed(2))
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        height.value = entityOptions.value.alt
 | 
			
		||||
      }
 | 
			
		||||
      break
 | 
			
		||||
    case 2:
 | 
			
		||||
    case '2':
 | 
			
		||||
      break
 | 
			
		||||
    case 3:
 | 
			
		||||
    case '3':
 | 
			
		||||
      let objectsToExclude = []
 | 
			
		||||
      for (let [key, value] of window.earth.entityMap) {
 | 
			
		||||
        if (value.type === 'RadarScanStereoscopic' && value.entity) {
 | 
			
		||||
          objectsToExclude.push(value.entity)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      entityOptions.value.getClampToHeight(entityOptions.value.options.position, objectsToExclude).then(h => {
 | 
			
		||||
        height.value = Number(h.toFixed(2))
 | 
			
		||||
        entityOptions.value.alt = Number(h.toFixed(2))
 | 
			
		||||
      })
 | 
			
		||||
      break
 | 
			
		||||
  }
 | 
			
		||||
  that.heightMode = val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const changLng = () => {
 | 
			
		||||
  projConvert()
 | 
			
		||||
  coordinateChange()
 | 
			
		||||
}
 | 
			
		||||
const changLat = () => {
 | 
			
		||||
  projConvert()
 | 
			
		||||
  coordinateChange()
 | 
			
		||||
}
 | 
			
		||||
const changAlt = () => {
 | 
			
		||||
  heightModeChange(heightMode.value)
 | 
			
		||||
  coordinateChange()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const changHeight = () => {
 | 
			
		||||
  switch (heightMode.value) {
 | 
			
		||||
    case 0:
 | 
			
		||||
      entityOptions.value.alt = Number(
 | 
			
		||||
        Number(height.value).toFixed(2)
 | 
			
		||||
      )
 | 
			
		||||
      break
 | 
			
		||||
    case 1:
 | 
			
		||||
      if (window.earth.viewer.scene.terrainProvider.availability) {
 | 
			
		||||
        Cesium.sampleTerrainMostDetailed(
 | 
			
		||||
          window.earth.viewer.scene.terrainProvider,
 | 
			
		||||
          [
 | 
			
		||||
            Cesium.Cartographic.fromDegrees(
 | 
			
		||||
              entityOptions.value.lng,
 | 
			
		||||
              entityOptions.value.lat
 | 
			
		||||
            )
 | 
			
		||||
          ]
 | 
			
		||||
        ).then(position => {
 | 
			
		||||
          entityOptions.value.alt =
 | 
			
		||||
            Number(height.value) +
 | 
			
		||||
            Number(position[0].height.toFixed(2))
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        entityOptions.value.alt = Number(height.value)
 | 
			
		||||
      }
 | 
			
		||||
      break
 | 
			
		||||
  }
 | 
			
		||||
  changAlt()
 | 
			
		||||
  coordinateChange()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const handleClick = () => { }
 | 
			
		||||
 | 
			
		||||
const formatChange = (val) => {
 | 
			
		||||
  switch (val) {
 | 
			
		||||
    case 1:
 | 
			
		||||
      format1.value = true
 | 
			
		||||
      format2.value = false
 | 
			
		||||
      format3.value = false
 | 
			
		||||
      break
 | 
			
		||||
    case 2:
 | 
			
		||||
      format1.value = false
 | 
			
		||||
      format2.value = true
 | 
			
		||||
      format3.value = false
 | 
			
		||||
      break
 | 
			
		||||
    case 3:
 | 
			
		||||
      format1.value = false
 | 
			
		||||
      format2.value = false
 | 
			
		||||
      format3.value = true
 | 
			
		||||
      break
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const projConvert = () => {
 | 
			
		||||
  let lng,
 | 
			
		||||
    lat,
 | 
			
		||||
    lngDM,
 | 
			
		||||
    latDM,
 | 
			
		||||
    lngDMS,
 | 
			
		||||
    latDMS,
 | 
			
		||||
    lngdnArr1,
 | 
			
		||||
    lngdnArr2,
 | 
			
		||||
    latdnArr1,
 | 
			
		||||
    latdnArr2,
 | 
			
		||||
    lngdnsArr1,
 | 
			
		||||
    lngdnsArr2,
 | 
			
		||||
    lngdnsArr3,
 | 
			
		||||
    latdnsArr1,
 | 
			
		||||
    latdnsArr2,
 | 
			
		||||
    latdnsArr3
 | 
			
		||||
  lng = entityOptions.value.lng
 | 
			
		||||
  lat = entityOptions.value.lat
 | 
			
		||||
  lngDM = that._proj.degreesToDMS(lng, true)
 | 
			
		||||
  latDM = that._proj.degreesToDMS(lat, true)
 | 
			
		||||
  lngdnArr1 = lngDM.split('°')
 | 
			
		||||
  lngdnArr2 = lngdnArr1[1].split("'")
 | 
			
		||||
  latdnArr1 = latDM.split('°')
 | 
			
		||||
  latdnArr2 = latdnArr1[1].split("'")
 | 
			
		||||
  lngDmD.value = lngdnArr1[0]
 | 
			
		||||
  lngDmM.value = lngdnArr2[0]
 | 
			
		||||
  latDmD.value = latdnArr1[0]
 | 
			
		||||
  latDmM.value = latdnArr2[0]
 | 
			
		||||
  lngDMS = that._proj.degreesToDMS(lng)
 | 
			
		||||
  latDMS = that._proj.degreesToDMS(lat)
 | 
			
		||||
  lngdnsArr1 = lngDMS.split('°')
 | 
			
		||||
  lngdnsArr2 = lngdnsArr1[1].split("'")
 | 
			
		||||
  lngdnsArr3 = lngdnsArr2[1].split('"')
 | 
			
		||||
  latdnsArr1 = latDMS.split('°')
 | 
			
		||||
  latdnsArr2 = latdnsArr1[1].split("'")
 | 
			
		||||
  latdnsArr3 = latdnsArr2[1].split('"')
 | 
			
		||||
  lngDmsD.value = lngdnsArr1[0]
 | 
			
		||||
  lngDmsM.value = lngdnsArr2[0]
 | 
			
		||||
  lngDmsS.value = lngdnsArr3[0]
 | 
			
		||||
  latDmsD.value = latdnsArr1[0]
 | 
			
		||||
  latDmsM.value = latdnsArr2[0]
 | 
			
		||||
  latDmsS.value = latdnsArr3[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const updateHeight = () => {
 | 
			
		||||
  entityOptions.value.updateHeight().then(() => {
 | 
			
		||||
    changAlt()
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const translate = () => {
 | 
			
		||||
  that.openPositionEditing(() => {
 | 
			
		||||
    changAlt()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
const confirm = () => {
 | 
			
		||||
  originalOptions = structuredClone(that.options)
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
  let params = structuredClone(that.options)
 | 
			
		||||
  delete params.host
 | 
			
		||||
  let params2 = {
 | 
			
		||||
    "id": params.id,
 | 
			
		||||
    "sourceName": params.name,
 | 
			
		||||
    "params": params,
 | 
			
		||||
    "isShow": params.show ? 1 : 0,
 | 
			
		||||
  }
 | 
			
		||||
  TreeApi.updateDirectoryInfo(params2)
 | 
			
		||||
  cusUpdateNode({"id": params.id, "sourceName": params.name, "params": JSON.stringify(params)})
 | 
			
		||||
}
 | 
			
		||||
const close = () => {
 | 
			
		||||
  baseDialog.value?.close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const clickChangeImage = () => {
 | 
			
		||||
  eventBus.emit("openImageSelect")
 | 
			
		||||
}
 | 
			
		||||
const clickChangeDefaultImage = () => {
 | 
			
		||||
  eventBus.emit("openImageSelect")
 | 
			
		||||
}
 | 
			
		||||
const fontChange = (val) => {
 | 
			
		||||
  entityOptions.value.labelFontFamily = val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.billboard-object {
 | 
			
		||||
  .YJ-custom-checkbox {
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -0,0 +1,494 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="曲线标注" left="180px" top="100px" className="polyline" :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 56%;">
 | 
			
		||||
            <div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col input-select-unit-box">
 | 
			
		||||
                  <el-select v-model="entityOptions.wordsName">
 | 
			
		||||
                    <el-option label="空间长度" value="0"></el-option>
 | 
			
		||||
                    <el-option label="投影长度" value="1"></el-option>
 | 
			
		||||
                    <el-option label="地表长度" value="2"></el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                  <input v-model="length" class="input-text" readonly="readonly">
 | 
			
		||||
                  <el-select v-model="lengthUnit">
 | 
			
		||||
                    <el-option label="米" value="m"></el-option>
 | 
			
		||||
                    <el-option label="千米" value="km"></el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <el-tabs v-model="activeName">
 | 
			
		||||
            <el-tab-pane label="属性信息" name="1">
 | 
			
		||||
              <attribute :entityOptions="entityOptions"></attribute>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane 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="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>
 | 
			
		||||
            </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" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">线条宽度</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth">
 | 
			
		||||
                    <span class="unit">px</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col input-select-line-type-box" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label">线条形式</span>
 | 
			
		||||
                  <el-select class="input input-select input-select-line-type" style="margin-left: 20px"
 | 
			
		||||
                    v-model="entityOptions.lineType" @change="lineTypechange">
 | 
			
		||||
                    <el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key">
 | 
			
		||||
                      <i class="yj-custom-icon" :class="item.icon"></i>
 | 
			
		||||
                      {{ item.name }}
 | 
			
		||||
                    </el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">线段缓冲</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.extend">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">缓冲宽度</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" data-min="0.01" max="999999"
 | 
			
		||||
                      v-model="entityOptions.extendWidth">
 | 
			
		||||
                    <span class="unit">m</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label">缓冲颜色</span>
 | 
			
		||||
                  <div class="extendColor" ref="extendColorRef"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">首尾反向</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">流动速率</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" max="999999" step="1"
 | 
			
		||||
                      v-model="entityOptions.speed">
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label lineSpace"
 | 
			
		||||
                    v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1 lineSpace" style="width: 80px;"
 | 
			
		||||
                    v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" max="4.5" step="0.1"
 | 
			
		||||
                      v-model="entityOptions.space">
 | 
			
		||||
                    <span class="unit">倍</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">首尾相连</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail">
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane label="标签风格" name="4">
 | 
			
		||||
              <labelStyle type="线" :entityOptions="entityOptions"></labelStyle>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
          </el-tabs>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </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">平移</button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <button @click="confirm">确定</button>
 | 
			
		||||
      <button @click="close">关闭</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, getCurrentInstance } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import { TreeApi } from '@/api/tree'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
import { initMapData } from '../tree/initMapData'
 | 
			
		||||
import { getFontList } from './fontSelect'
 | 
			
		||||
import attribute from './attribute.vue'
 | 
			
		||||
import labelStyle from './labelStyle.vue'
 | 
			
		||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
 | 
			
		||||
 | 
			
		||||
const { cusUpdateNode } = useTreeNode()
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
 | 
			
		||||
const length = ref(0)
 | 
			
		||||
const lengthUnit = ref('m')
 | 
			
		||||
const fontList = ref(getFontList())
 | 
			
		||||
const height = ref(10)
 | 
			
		||||
const heightModeData = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '海拔高度',
 | 
			
		||||
    value: '海拔高度',
 | 
			
		||||
    key: 0
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '相对地表',
 | 
			
		||||
    value: '相对地表',
 | 
			
		||||
    key: 1
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '依附模型',
 | 
			
		||||
    value: '依附模型',
 | 
			
		||||
    key: 2
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
const lineTypeData = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '实线',
 | 
			
		||||
    value: '实线',
 | 
			
		||||
    key: 0,
 | 
			
		||||
    icon: 'line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '虚线',
 | 
			
		||||
    value: '虚线',
 | 
			
		||||
    key: 1,
 | 
			
		||||
    icon: 'dash-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '泛光',
 | 
			
		||||
    value: '泛光',
 | 
			
		||||
    key: 2,
 | 
			
		||||
    icon: 'light-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '尾迹光线',
 | 
			
		||||
    value: '尾迹光线',
 | 
			
		||||
    key: 3,
 | 
			
		||||
    icon: 'tail-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '多尾迹光线',
 | 
			
		||||
    value: '多尾迹光线',
 | 
			
		||||
    key: 4,
 | 
			
		||||
    icon: 'mult-tail-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动虚线1',
 | 
			
		||||
    value: '流动虚线1',
 | 
			
		||||
    key: 5,
 | 
			
		||||
    icon: 'flow-dash-line1'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动虚线2',
 | 
			
		||||
    value: '流动虚线2',
 | 
			
		||||
    key: 6,
 | 
			
		||||
    icon: 'flow-dash-line2'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头1',
 | 
			
		||||
    value: '流动箭头1',
 | 
			
		||||
    key: 7,
 | 
			
		||||
    icon: 'pic-line1'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头2',
 | 
			
		||||
    value: '流动箭头2',
 | 
			
		||||
    key: 8,
 | 
			
		||||
    icon: 'pic-line2'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头3',
 | 
			
		||||
    value: '流动箭头3',
 | 
			
		||||
    key: 9,
 | 
			
		||||
    icon: 'pic-line3'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头4',
 | 
			
		||||
    value: '流动箭头4',
 | 
			
		||||
    key: 10,
 | 
			
		||||
    icon: 'pic-line4'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头5',
 | 
			
		||||
    value: '流动箭头5',
 | 
			
		||||
    key: 11,
 | 
			
		||||
    icon: 'pic-line5'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头6',
 | 
			
		||||
    value: '流动箭头6',
 | 
			
		||||
    key: 12,
 | 
			
		||||
    icon: 'pic-line6'
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
const activeName = ref('1')
 | 
			
		||||
const activeTd = ref({
 | 
			
		||||
  index: -1,
 | 
			
		||||
  name: ''
 | 
			
		||||
})
 | 
			
		||||
const entityOptions = ref({});
 | 
			
		||||
const linePositions = ref([])
 | 
			
		||||
const colorRef = ref(null)
 | 
			
		||||
const extendColorRef = ref(null)
 | 
			
		||||
const heightMode = ref(0)
 | 
			
		||||
 | 
			
		||||
let originalOptions
 | 
			
		||||
let that
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const open = async (id) => {
 | 
			
		||||
  that = window.earth.entityMap.get(id)
 | 
			
		||||
  originalOptions = structuredClone(that.options)
 | 
			
		||||
  entityOptions.value = that
 | 
			
		||||
  heightMode.value = entityOptions.value.heightMode
 | 
			
		||||
  length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
  linePositions.value = structuredClone(that.options.positions)
 | 
			
		||||
  that.lengthChangeCallBack = ()=>{
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
  heightModeChange(heightMode.value)
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  let colorPicker = new 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 extendColorPicker = new YJColorPicker({
 | 
			
		||||
    el: extendColorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: entityOptions.value.extendColor,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      entityOptions.value.extendColor = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      entityOptions.value.extendColor = 'rgba(255,255,255,1)'
 | 
			
		||||
    } //点击清空按钮事件回调
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const heightModeChange = (val) => {
 | 
			
		||||
  that.heightMode = heightMode.value
 | 
			
		||||
}
 | 
			
		||||
const heightConfirm = () => {
 | 
			
		||||
  that.positionEditing = false
 | 
			
		||||
  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))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const inputDblclick = async (event, i, anme) => {
 | 
			
		||||
  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) => {
 | 
			
		||||
  entityOptions.value.options.positions[i][name] = Number(Number(event.target.value).toFixed(digit))
 | 
			
		||||
  entityOptions.value.positionEditing = false
 | 
			
		||||
  activeTd.value = {
 | 
			
		||||
    index: -1,
 | 
			
		||||
    name: ''
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const lineTypechange = () => {
 | 
			
		||||
}
 | 
			
		||||
const nodeEdit = () => {
 | 
			
		||||
  entityOptions.value.positionEditing = false
 | 
			
		||||
  entityOptions.value.noseToTail = false
 | 
			
		||||
  heightMode.value = 0
 | 
			
		||||
  that.heightMode = 0
 | 
			
		||||
  that.nodeEdit((positions, lenByMeter) => {
 | 
			
		||||
    entityOptions.value.options.positions = structuredClone(positions)
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
      length.value = lenByMeter / 1000
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      length.value = lenByMeter
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const translate = () => {
 | 
			
		||||
  that.openPositionEditing(() => {
 | 
			
		||||
    entityOptions.value.options.positions = structuredClone(that.options.positions)
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
      length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const closeCallback = () => {
 | 
			
		||||
  entityOptions.value.originalOptions = structuredClone(originalOptions)
 | 
			
		||||
  that.positionEditing = false
 | 
			
		||||
  entityOptions.value.closeNodeEdit()
 | 
			
		||||
  entityOptions.value.reset()
 | 
			
		||||
  eventBus.emit("destroyComponent")
 | 
			
		||||
}
 | 
			
		||||
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(
 | 
			
		||||
  () => lengthUnit.value,
 | 
			
		||||
  (val) => {
 | 
			
		||||
    if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
 | 
			
		||||
      if (lengthUnit.value == 'km') {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  { immediate: true }
 | 
			
		||||
);
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.polyline {
 | 
			
		||||
  ::v-deep .input-select-unit-box {
 | 
			
		||||
    .el-input-group__prepend {
 | 
			
		||||
      width: 100px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-input__wrapper {
 | 
			
		||||
      width: 130px;
 | 
			
		||||
      padding: 0;
 | 
			
		||||
      background: rgba(0, 0, 0, 0.5);
 | 
			
		||||
      box-shadow: unset;
 | 
			
		||||
 | 
			
		||||
      .el-input__inner {
 | 
			
		||||
        border-radius: 0;
 | 
			
		||||
        background: unset;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-input-group__append {
 | 
			
		||||
      width: 75px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										1037
									
								
								src/renderer/src/views/components/propertyBox/elm_html.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1037
									
								
								src/renderer/src/views/components/propertyBox/elm_html.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										48
									
								
								src/renderer/src/views/components/propertyBox/fontSelect.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/renderer/src/views/components/propertyBox/fontSelect.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
let fontData = [
 | 
			
		||||
  {
 | 
			
		||||
    name: '黑体',
 | 
			
		||||
    value: '黑体',
 | 
			
		||||
    font: 'SimHei',
 | 
			
		||||
    key: 0
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '思源黑体',
 | 
			
		||||
    value: '思源黑体',
 | 
			
		||||
    font: 'SourceHanSansTi',
 | 
			
		||||
    key: 1
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '庞门正道标题体',
 | 
			
		||||
    value: '庞门正道标题体',
 | 
			
		||||
    font: 'PMZDBTTi',
 | 
			
		||||
    key: 2
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '数黑体',
 | 
			
		||||
    value: '数黑体',
 | 
			
		||||
    font: 'AlimamaShuHeiTi',
 | 
			
		||||
    key: 3
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
function getFontList() {
 | 
			
		||||
  return fontData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getFontFamily(key) {
 | 
			
		||||
  for (let i = 0; i < fontData.length; i++) {
 | 
			
		||||
    if (fontData[i].key == key) {
 | 
			
		||||
      return fontData[i].font;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getFontFamilyName(key) {
 | 
			
		||||
  for (let i = 0; i < fontData.length; i++) {
 | 
			
		||||
    if (fontData[i].key == key) {
 | 
			
		||||
      return fontData[i].name;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { getFontList, getFontFamily, getFontFamilyName }
 | 
			
		||||
							
								
								
									
										119
									
								
								src/renderer/src/views/components/propertyBox/labelStyle.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/renderer/src/views/components/propertyBox/labelStyle.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">新增{{ type }}标签风格设置</span>
 | 
			
		||||
        <button style="margin-right: 56px;">初始风格</button>
 | 
			
		||||
        <button>当前风格</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <span class="custom-divider"></span>
 | 
			
		||||
    <div class="row"></div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label" style="margin-right: 42px;">标签设置</span>
 | 
			
		||||
        <span class="label">标签显示</span>
 | 
			
		||||
        <input class="btn-switch" type="checkbox" v-model="entityOptions.labelShow">
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col" style="flex: 0 0 114px;">
 | 
			
		||||
        <span class="label">视野缩放</span>
 | 
			
		||||
        <input class="btn-switch" type="checkbox" v-model="entityOptions.labelScaleByDistance">
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">最近距离</span>
 | 
			
		||||
        <div class="input-number input-number-unit-1">
 | 
			
		||||
          <input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelNear">
 | 
			
		||||
          <span class="unit">m</span>
 | 
			
		||||
          <span class="arrow"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">最远距离</span>
 | 
			
		||||
        <div class="input-number input-number-unit-1">
 | 
			
		||||
          <input class="input" type="number" title="" min="1" max="99999999" v-model="entityOptions.labelFar">
 | 
			
		||||
          <span class="unit">m</span>
 | 
			
		||||
          <span class="arrow"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <span class="custom-divider"></span>
 | 
			
		||||
    <div class="row"></div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">字体样式</span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col" style="flex: 0 0 114px;">
 | 
			
		||||
        <span class="label">字体颜色</span>
 | 
			
		||||
        <div class="labelColor" ref="labelColorRef"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <span class="label">字体大小</span>
 | 
			
		||||
        <div class="input-number input-number-unit-2">
 | 
			
		||||
          <input class="input" type="number" title="" min="1" max="99" v-model="entityOptions.labelFontSize">
 | 
			
		||||
          <span class="unit">px</span>
 | 
			
		||||
          <span class="arrow"></span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col font-select-box">
 | 
			
		||||
        <span class="label" style="flex: none;">字体选择</span>
 | 
			
		||||
        <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>
 | 
			
		||||
        </el-select>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- <div class="row">
 | 
			
		||||
      <div class="col" style="flex: 0 0 114px;">
 | 
			
		||||
        <span class="label">轮廓颜色</span>
 | 
			
		||||
        <div class="outlineColor"></div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div> -->
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import { getFontList } from './fontSelect'
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  type: {
 | 
			
		||||
    type: String,
 | 
			
		||||
    default: ''
 | 
			
		||||
  },
 | 
			
		||||
  entityOptions: {
 | 
			
		||||
    type: Object,
 | 
			
		||||
    default: {}
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
const entityOptions = ref(props.entityOptions)
 | 
			
		||||
const fontList = ref(getFontList())
 | 
			
		||||
const labelColorRef = ref(null)
 | 
			
		||||
 | 
			
		||||
const fontChange = (val) => {
 | 
			
		||||
  entityOptions.value.labelFontFamily = val
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  let labelColorPicker = new YJColorPicker({
 | 
			
		||||
    el: labelColorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: entityOptions.value.labelColor,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      entityOptions.value.labelColor = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      entityOptions.value.labelColor = 'rgba(255,255,255,1)'
 | 
			
		||||
    } //点击清空按钮事件回调
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
							
								
								
									
										214
									
								
								src/renderer/src/views/components/propertyBox/polygonObject.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								src/renderer/src/views/components/propertyBox/polygonObject.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,214 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="面属性" left="180px" top="100px" :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="options.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="readonly" type="text">
 | 
			
		||||
                <div class="input-select-unit"></div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <el-tabs v-model="activeName" @tab-click="handleClick">
 | 
			
		||||
            <el-tab-pane label="属性信息" name="1">
 | 
			
		||||
              <attribute></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>
 | 
			
		||||
                  <div class="height-mode"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">Z值统一增加</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1 height-box">
 | 
			
		||||
                    <input class="input height" type="number" title="" min="-9999999" max="999999999">
 | 
			
		||||
                    <span class="unit">m</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <button class="confirm height-confirm" style="margin-left: 5px;">确认</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>
 | 
			
		||||
                </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" @model="lineWidth">
 | 
			
		||||
                    <span class="unit">px</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane label="标签风格" name="5">角色管理</el-tab-pane>
 | 
			
		||||
          </el-tabs>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <span class="custom-divider"></span>
 | 
			
		||||
    </template>
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button>确定</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
import attribute from './attribute.vue'
 | 
			
		||||
 | 
			
		||||
const activeName = ref('1')
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const options = ref({});
 | 
			
		||||
const colorRef = ref(null)
 | 
			
		||||
const lineColorRef = ref(null)
 | 
			
		||||
eventBus.on("openPolygonEdit", () => {
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const lineWidth = ref('')
 | 
			
		||||
 | 
			
		||||
const open = async (id) => {
 | 
			
		||||
  let that = window.earth.entityMap.get(id)
 | 
			
		||||
  options.value = structuredClone(that.options)
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  let colorPicker = new YJColorPicker({
 | 
			
		||||
    el: colorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: options.value.color,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      options.value.color = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      options.value.color = 'rgba(255,255,255,1)'
 | 
			
		||||
    } //点击清空按钮事件回调
 | 
			
		||||
  })
 | 
			
		||||
  let linecolorPicker = new YJColorPicker({
 | 
			
		||||
    el: lineColorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: options.value.lineColor,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      options.value.lineColor = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      options.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 closeCallback = () => {
 | 
			
		||||
  console.log('closeCallback');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss"></style>
 | 
			
		||||
							
								
								
									
										501
									
								
								src/renderer/src/views/components/propertyBox/polylineObject.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										501
									
								
								src/renderer/src/views/components/propertyBox/polylineObject.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,501 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <Dialog ref="baseDialog" title="线标注" left="180px" top="100px" className="polyline" :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 56%;">
 | 
			
		||||
            <div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col input-select-unit-box">
 | 
			
		||||
                  <el-select v-model="entityOptions.wordsName">
 | 
			
		||||
                    <el-option label="空间长度" :value="0"></el-option>
 | 
			
		||||
                    <el-option label="投影长度" :value="1"></el-option>
 | 
			
		||||
                    <el-option label="地表长度" :value="2"></el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                  <input v-model="length" class="input-text" readonly="readonly">
 | 
			
		||||
                  <el-select v-model="lengthUnit">
 | 
			
		||||
                    <el-option label="米" value="m"></el-option>
 | 
			
		||||
                    <el-option label="千米" value="km"></el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="div-item">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
          <el-tabs v-model="activeName">
 | 
			
		||||
            <el-tab-pane label="属性信息" name="1">
 | 
			
		||||
              <attribute :entityOptions="entityOptions"></attribute>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane 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="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>
 | 
			
		||||
            </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" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">线条宽度</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="1" max="999" v-model="entityOptions.lineWidth">
 | 
			
		||||
                    <span class="unit">px</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col input-select-line-type-box" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label">线条形式</span>
 | 
			
		||||
                  <el-select class="input input-select input-select-line-type" style="margin-left: 20px"
 | 
			
		||||
                    v-model="entityOptions.lineType" @change="lineTypechange">
 | 
			
		||||
                    <el-option v-for="item in lineTypeData" :key="item.key" :label="item.name" :value="item.key">
 | 
			
		||||
                      <i class="yj-custom-icon" :class="item.icon"></i>
 | 
			
		||||
                      {{ item.name }}
 | 
			
		||||
                    </el-option>
 | 
			
		||||
                  </el-select>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">首尾相连</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.noseToTail">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">线段圆滑</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.smooth">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 37%;">
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">线段缓冲</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.extend">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">缓冲宽度</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" data-min="0.01" max="999999"
 | 
			
		||||
                      v-model="entityOptions.extendWidth">
 | 
			
		||||
                    <span class="unit">m</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label">缓冲颜色</span>
 | 
			
		||||
                  <div class="extendColor" ref="extendColorRef"></div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div class="row" v-show="entityOptions.lineType > 2 && entityOptions.lineType < 13">
 | 
			
		||||
                <div class="col">
 | 
			
		||||
                  <span class="label">首尾反向</span>
 | 
			
		||||
                  <input class="btn-switch" type="checkbox" v-model="entityOptions.rotate">
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 33%;">
 | 
			
		||||
                  <span class="label">流动速率</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1" style="width: 80px;">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" max="999999" step="1"
 | 
			
		||||
                      v-model="entityOptions.speed">
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col" style="flex: 0 0 37%;">
 | 
			
		||||
                  <span class="label lineSpace"
 | 
			
		||||
                    v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">线条间距</span>
 | 
			
		||||
                  <div class="input-number input-number-unit-1 lineSpace" style="width: 80px;"
 | 
			
		||||
                    v-show="entityOptions.lineType > 2 && entityOptions.lineType >= 5">
 | 
			
		||||
                    <input class="input" type="number" title="" min="0" max="4.5" step="0.1"
 | 
			
		||||
                      v-model="entityOptions.space">
 | 
			
		||||
                    <span class="unit">倍</span>
 | 
			
		||||
                    <span class="arrow"></span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
            <el-tab-pane label="标签风格" name="4">
 | 
			
		||||
              <labelStyle type="线" :entityOptions="entityOptions"></labelStyle>
 | 
			
		||||
            </el-tab-pane>
 | 
			
		||||
          </el-tabs>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </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">平移</button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <button @click="confirm">确定</button>
 | 
			
		||||
      <button @click="close">关闭</button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, getCurrentInstance } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import { TreeApi } from '@/api/tree'
 | 
			
		||||
import Dialog from '@/components/dialog/baseDialog.vue'
 | 
			
		||||
import { initMapData } from '../tree/initMapData'
 | 
			
		||||
import { getFontList } from './fontSelect'
 | 
			
		||||
import attribute from './attribute.vue'
 | 
			
		||||
import labelStyle from './labelStyle.vue'
 | 
			
		||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
 | 
			
		||||
 | 
			
		||||
const { cusUpdateNode } = useTreeNode()
 | 
			
		||||
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
 | 
			
		||||
const length = ref(0)
 | 
			
		||||
const lengthUnit = ref('m')
 | 
			
		||||
const fontList = ref(getFontList())
 | 
			
		||||
const height = ref(10)
 | 
			
		||||
const heightModeData = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '海拔高度',
 | 
			
		||||
    value: '海拔高度',
 | 
			
		||||
    key: 0
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '相对地表',
 | 
			
		||||
    value: '相对地表',
 | 
			
		||||
    key: 1
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '依附模型',
 | 
			
		||||
    value: '依附模型',
 | 
			
		||||
    key: 2
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
const lineTypeData = ref([
 | 
			
		||||
  {
 | 
			
		||||
    name: '实线',
 | 
			
		||||
    value: '实线',
 | 
			
		||||
    key: 0,
 | 
			
		||||
    icon: 'line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '虚线',
 | 
			
		||||
    value: '虚线',
 | 
			
		||||
    key: 1,
 | 
			
		||||
    icon: 'dash-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '泛光',
 | 
			
		||||
    value: '泛光',
 | 
			
		||||
    key: 2,
 | 
			
		||||
    icon: 'light-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '尾迹光线',
 | 
			
		||||
    value: '尾迹光线',
 | 
			
		||||
    key: 3,
 | 
			
		||||
    icon: 'tail-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '多尾迹光线',
 | 
			
		||||
    value: '多尾迹光线',
 | 
			
		||||
    key: 4,
 | 
			
		||||
    icon: 'mult-tail-line'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动虚线1',
 | 
			
		||||
    value: '流动虚线1',
 | 
			
		||||
    key: 5,
 | 
			
		||||
    icon: 'flow-dash-line1'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动虚线2',
 | 
			
		||||
    value: '流动虚线2',
 | 
			
		||||
    key: 6,
 | 
			
		||||
    icon: 'flow-dash-line2'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头1',
 | 
			
		||||
    value: '流动箭头1',
 | 
			
		||||
    key: 7,
 | 
			
		||||
    icon: 'pic-line1'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头2',
 | 
			
		||||
    value: '流动箭头2',
 | 
			
		||||
    key: 8,
 | 
			
		||||
    icon: 'pic-line2'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头3',
 | 
			
		||||
    value: '流动箭头3',
 | 
			
		||||
    key: 9,
 | 
			
		||||
    icon: 'pic-line3'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头4',
 | 
			
		||||
    value: '流动箭头4',
 | 
			
		||||
    key: 10,
 | 
			
		||||
    icon: 'pic-line4'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头5',
 | 
			
		||||
    value: '流动箭头5',
 | 
			
		||||
    key: 11,
 | 
			
		||||
    icon: 'pic-line5'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: '流动箭头6',
 | 
			
		||||
    value: '流动箭头6',
 | 
			
		||||
    key: 12,
 | 
			
		||||
    icon: 'pic-line6'
 | 
			
		||||
  }
 | 
			
		||||
])
 | 
			
		||||
const activeName = ref('1')
 | 
			
		||||
const activeTd = ref({
 | 
			
		||||
  index: -1,
 | 
			
		||||
  name: ''
 | 
			
		||||
})
 | 
			
		||||
const entityOptions = ref({});
 | 
			
		||||
const linePositions = ref([])
 | 
			
		||||
const colorRef = ref(null)
 | 
			
		||||
const extendColorRef = ref(null)
 | 
			
		||||
const heightMode = ref(0)
 | 
			
		||||
 | 
			
		||||
let originalOptions
 | 
			
		||||
let that
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const open = async (id) => {
 | 
			
		||||
  that = window.earth.entityMap.get(id)
 | 
			
		||||
  originalOptions = structuredClone(that.options)
 | 
			
		||||
  entityOptions.value = that
 | 
			
		||||
  heightMode.value = entityOptions.value.heightMode
 | 
			
		||||
  length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
  linePositions.value = structuredClone(that.options.positions)
 | 
			
		||||
  that.lengthChangeCallBack = ()=>{
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
  heightModeChange(heightMode.value)
 | 
			
		||||
  baseDialog.value?.open()
 | 
			
		||||
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  let colorPicker = new 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 extendColorPicker = new YJColorPicker({
 | 
			
		||||
    el: extendColorRef.value,
 | 
			
		||||
    size: 'mini', //颜色box类型
 | 
			
		||||
    alpha: true, //是否开启透明度
 | 
			
		||||
    defaultColor: entityOptions.value.extendColor,
 | 
			
		||||
    disabled: false, //是否禁止打开颜色选择器
 | 
			
		||||
    openPickerAni: 'opacity', //打开颜色选择器动画
 | 
			
		||||
    sure: color => {
 | 
			
		||||
      entityOptions.value.extendColor = color
 | 
			
		||||
    }, //点击确认按钮事件回调
 | 
			
		||||
    clear: () => {
 | 
			
		||||
      entityOptions.value.extendColor = 'rgba(255,255,255,1)'
 | 
			
		||||
    } //点击清空按钮事件回调
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const heightModeChange = (val) => {
 | 
			
		||||
  that.heightMode = heightMode.value
 | 
			
		||||
}
 | 
			
		||||
const heightConfirm = () => {
 | 
			
		||||
  that.positionEditing = false
 | 
			
		||||
  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))
 | 
			
		||||
  }
 | 
			
		||||
  that.smooth = that.smooth
 | 
			
		||||
}
 | 
			
		||||
const inputDblclick = async (event, i, anme) => {
 | 
			
		||||
  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) => {
 | 
			
		||||
  entityOptions.value.options.positions[i][name] = Number(Number(event.target.value).toFixed(digit))
 | 
			
		||||
  entityOptions.value.positionEditing = false
 | 
			
		||||
  activeTd.value = {
 | 
			
		||||
    index: -1,
 | 
			
		||||
    name: ''
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const lineTypechange = () => {
 | 
			
		||||
}
 | 
			
		||||
const nodeEdit = () => {
 | 
			
		||||
  entityOptions.value.positionEditing = false
 | 
			
		||||
  entityOptions.value.noseToTail = false
 | 
			
		||||
  heightMode.value = 0
 | 
			
		||||
  that.heightMode = 0
 | 
			
		||||
  that.nodeEdit((positions, lenByMeter) => {
 | 
			
		||||
    entityOptions.value.options.positions = structuredClone(positions)
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
      length.value = lenByMeter / 1000
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      length.value = lenByMeter
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
const translate = () => {
 | 
			
		||||
  that.openPositionEditing(() => {
 | 
			
		||||
    entityOptions.value.options.positions = structuredClone(that.options.positions)
 | 
			
		||||
    if (lengthUnit.value == 'km') {
 | 
			
		||||
      length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const closeCallback = () => {
 | 
			
		||||
  entityOptions.value.originalOptions = structuredClone(originalOptions)
 | 
			
		||||
  that.positionEditing = false
 | 
			
		||||
  entityOptions.value.closeNodeEdit()
 | 
			
		||||
  entityOptions.value.reset()
 | 
			
		||||
  eventBus.emit("destroyComponent")
 | 
			
		||||
}
 | 
			
		||||
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(
 | 
			
		||||
  () => lengthUnit.value,
 | 
			
		||||
  (val) => {
 | 
			
		||||
    if (entityOptions.value.lengthByMeter || entityOptions.value.lengthByMeter == 0) {
 | 
			
		||||
      if (lengthUnit.value == 'km') {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter / 1000
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        length.value = entityOptions.value.lengthByMeter
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  { immediate: true }
 | 
			
		||||
);
 | 
			
		||||
defineExpose({
 | 
			
		||||
  open
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.polyline {
 | 
			
		||||
  ::v-deep .input-select-unit-box {
 | 
			
		||||
    .el-input-group__prepend {
 | 
			
		||||
      width: 100px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-input__wrapper {
 | 
			
		||||
      width: 130px;
 | 
			
		||||
      padding: 0;
 | 
			
		||||
      background: rgba(0, 0, 0, 0.5);
 | 
			
		||||
      box-shadow: unset;
 | 
			
		||||
 | 
			
		||||
      .el-input__inner {
 | 
			
		||||
        border-radius: 0;
 | 
			
		||||
        background: unset;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .el-input-group__append {
 | 
			
		||||
      width: 75px;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										188
									
								
								src/renderer/src/views/components/propertyBox/richText.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								src/renderer/src/views/components/propertyBox/richText.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,188 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="richText-box" v-if="visible">
 | 
			
		||||
    <div class="richText-box-mask"></div>
 | 
			
		||||
    <div class="richText-content">
 | 
			
		||||
      <div class="richText-header">
 | 
			
		||||
        <p>{{ title }}</P>
 | 
			
		||||
        <i class="close" @click="close">✕</i>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div ref="toolbarContainer" id="toolbar-container"></div>
 | 
			
		||||
      <div ref="editorContainer" id="editor-container"></div>
 | 
			
		||||
      <div class="richText-footer">
 | 
			
		||||
        <button class="primary" @click="confirm">确认</button>
 | 
			
		||||
        <button class="cancel">取消</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { ref, nextTick } from 'vue';
 | 
			
		||||
import { inject } from "vue";
 | 
			
		||||
import { GisApi } from '@/api/gisApi'
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const host = window.location.host
 | 
			
		||||
const visible = ref(false)
 | 
			
		||||
const baseDialog = ref(null);
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const toolbarContainer = ref()
 | 
			
		||||
const editorContainer = ref()
 | 
			
		||||
 | 
			
		||||
const title = ref('')
 | 
			
		||||
 | 
			
		||||
let editor: any
 | 
			
		||||
const upload = async (file) => {
 | 
			
		||||
  const formData = new FormData();
 | 
			
		||||
  formData.append('files', file);
 | 
			
		||||
  let res = await GisApi.linkFile(formData)
 | 
			
		||||
  if (res.code == 0 || res.code == 200) {
 | 
			
		||||
    let url = res.data[0].previewUrl
 | 
			
		||||
    if(url && url[0] === '/') {
 | 
			
		||||
      url = url.slice(1)
 | 
			
		||||
    }
 | 
			
		||||
    return url
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const open = (t = '', content = '') => {
 | 
			
		||||
  title.value = t
 | 
			
		||||
  visible.value = true
 | 
			
		||||
  nextTick(() => {
 | 
			
		||||
    const { createEditor, createToolbar } = window.wangEditor
 | 
			
		||||
    const editorConfig = {
 | 
			
		||||
      placeholder: '请输入正文...',
 | 
			
		||||
      MENU_CONF: {
 | 
			
		||||
        uploadImage: {
 | 
			
		||||
          fieldName: 'file',
 | 
			
		||||
          // maxFileSize: 50 * 1024 * 1024,
 | 
			
		||||
          // base64LimitSize: 50 * 1024 * 1024, // 50M 以下插入 base64
 | 
			
		||||
          server: undefined,
 | 
			
		||||
          // // 上传之前触发
 | 
			
		||||
          // onBeforeUpload(file) { // TS 语法
 | 
			
		||||
          //   // onBeforeUpload(file) {    // JS 语法
 | 
			
		||||
          //   // file 选中的文件,格式如 { key: file }
 | 
			
		||||
          //   return file
 | 
			
		||||
 | 
			
		||||
          //   // 可以 return
 | 
			
		||||
          //   // 1. return file 或者 new 一个 file ,接下来将上传
 | 
			
		||||
          //   // 2. return false ,不上传这个 file
 | 
			
		||||
          // },
 | 
			
		||||
 | 
			
		||||
          // // 上传进度的回调函数
 | 
			
		||||
          // onProgress(progress) {  // TS 语法
 | 
			
		||||
          //   // onProgress(progress) {       // JS 语法
 | 
			
		||||
          //   // progress 是 0-100 的数字
 | 
			
		||||
          //   console.log('progress', progress)
 | 
			
		||||
          // },
 | 
			
		||||
 | 
			
		||||
          // // 单个文件上传成功之后
 | 
			
		||||
          // onSuccess(file, res) {  // TS 语法
 | 
			
		||||
          //   // onSuccess(file, res) {          // JS 语法
 | 
			
		||||
          //   console.log(`${file.name} 上传成功`, res)
 | 
			
		||||
          // },
 | 
			
		||||
 | 
			
		||||
          // // 单个文件上传失败
 | 
			
		||||
          // onFailed(file, res) {   // TS 语法
 | 
			
		||||
          //   // onFailed(file, res) {           // JS 语法
 | 
			
		||||
          //   console.log(`${file.name} 上传失败`, res)
 | 
			
		||||
          // },
 | 
			
		||||
 | 
			
		||||
          // // 上传错误,或者触发 timeout 超时
 | 
			
		||||
          // onError(file, err, res) {  // TS 语法
 | 
			
		||||
          //   // onError(file, err, res) {               // JS 语法
 | 
			
		||||
          //   console.log(`${file.name} 上传出错`, err, res)
 | 
			
		||||
          // },
 | 
			
		||||
 | 
			
		||||
          // 自定义上传
 | 
			
		||||
          async customUpload(file: any, insertFn: (arg0: string) => void) {  // TS 语法
 | 
			
		||||
            // async customUpload(file, insertFn) {                   // JS 语法
 | 
			
		||||
            // file 即选中的文件
 | 
			
		||||
            // 自己实现上传,并得到图片 url alt href
 | 
			
		||||
            // 最后插入图片
 | 
			
		||||
            let url = await upload(file)
 | 
			
		||||
            insertFn(host + '/' + url)
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        uploadVideo: {
 | 
			
		||||
          // maxFileSize: 500 * 1024 * 1024,
 | 
			
		||||
          server: undefined,
 | 
			
		||||
          allowedFileTypes: ['video/mp4', 'video/mp3', 'video/ogg', 'video/webm', 'video/avi'],
 | 
			
		||||
          // 自定义上传
 | 
			
		||||
          async customUpload(file: any, insertFn: (arg0: string) => void) {
 | 
			
		||||
            // async customUpload(file, insertFn) {
 | 
			
		||||
            // file 即选中的文件
 | 
			
		||||
            // 自己实现上传,并得到图片 url alt href
 | 
			
		||||
            // 最后插入图片
 | 
			
		||||
            let url = await upload(file)
 | 
			
		||||
            insertFn(host + '/' + url)
 | 
			
		||||
            // if(_this.#customUploadVideo) {
 | 
			
		||||
            //   let url = await _this.#customUploadVideo(file)
 | 
			
		||||
            //   insertFn(url, file.name)
 | 
			
		||||
            // }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      onChange(editor: { getHtml: () => any; }) {
 | 
			
		||||
        const html = editor.getHtml()
 | 
			
		||||
        // 也可以同步到 <textarea>
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    editor = createEditor({
 | 
			
		||||
      selector: '#editor-container',
 | 
			
		||||
      html: '<p><br></p>',
 | 
			
		||||
      config: editorConfig,
 | 
			
		||||
      mode: 'default', // or 'simple'
 | 
			
		||||
    })
 | 
			
		||||
    const toolbarConfig = {
 | 
			
		||||
      // 隐藏菜单
 | 
			
		||||
      excludeKeys: [
 | 
			
		||||
        'emotion', // 表情
 | 
			
		||||
        'insertImage', // 网络图片
 | 
			
		||||
        'insertVideo' // 网络视频
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
    const toolbar = createToolbar({
 | 
			
		||||
      editor: editor,
 | 
			
		||||
      selector: '#toolbar-container',
 | 
			
		||||
      config: toolbarConfig,
 | 
			
		||||
      mode: 'default', // or 'simple'
 | 
			
		||||
    })
 | 
			
		||||
    editor.on('fullScreen', () => { console.log('fullScreen') })
 | 
			
		||||
    editor.setHtml(content)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
const close = () => {
 | 
			
		||||
  visible.value = false
 | 
			
		||||
  toolbarContainer.value.innerHTML = ''
 | 
			
		||||
  editorContainer.value.innerHTML = ''
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let confirmRichText
 | 
			
		||||
 | 
			
		||||
const confirm = () => {
 | 
			
		||||
  let html = editor.getHtml()
 | 
			
		||||
  confirmRichText && confirmRichText(html)
 | 
			
		||||
  close()
 | 
			
		||||
  confirmRichText = undefined
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
eventBus.on("openRichText", (t = '', content = '', confirmCallBack) => {
 | 
			
		||||
  open(t, content)
 | 
			
		||||
  confirmRichText = confirmCallBack
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped lang="scss">
 | 
			
		||||
.richText-header {
 | 
			
		||||
  p {
 | 
			
		||||
    color: #000;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .close {
 | 
			
		||||
    color: #000;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
@ -6,7 +6,6 @@
 | 
			
		||||
    <template #footer>
 | 
			
		||||
      <button>确定</button>
 | 
			
		||||
    </template>
 | 
			
		||||
 | 
			
		||||
  </Dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
export const useRightMenu = () => {
 | 
			
		||||
  const itemClick = (menuItem: any) => {
 | 
			
		||||
    return menuItem.callback()
 | 
			
		||||
  const itemClick = (menuItem: any, eventBus) => {
 | 
			
		||||
    return menuItem.callback(eventBus)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return { itemClick }
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
 | 
			
		||||
import { useTreeNode } from '@/views/components/tree/hooks/treeNode'
 | 
			
		||||
 | 
			
		||||
export const useRightOperate = () => {
 | 
			
		||||
  const { getSelectedNodes, cusRemoveNode } = useTreeNode()
 | 
			
		||||
  const { getSelectedNodes, cusRemoveNode, cusUpdateNode } = useTreeNode()
 | 
			
		||||
 | 
			
		||||
  //添加文件
 | 
			
		||||
  const addDirectory = () => {
 | 
			
		||||
@ -25,7 +25,14 @@ export const useRightOperate = () => {
 | 
			
		||||
  //导入模型
 | 
			
		||||
  const addTrajectory = () => {}
 | 
			
		||||
  //编辑
 | 
			
		||||
  const editNode = () => {}
 | 
			
		||||
  const editNode = (eventBus) => {
 | 
			
		||||
    let selectNodes = getSelectedNodes(window.treeObj);
 | 
			
		||||
    if(selectNodes && selectNodes[selectNodes.length-1]) {
 | 
			
		||||
      let params = JSON.parse(selectNodes[selectNodes.length-1].params)
 | 
			
		||||
      console.log('params', params)
 | 
			
		||||
      eventBus.emit("openDialog", selectNodes[selectNodes.length-1].sourceType, params.id);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //删除
 | 
			
		||||
  const deleteNode = (hasConfirm = true) => {
 | 
			
		||||
    ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', {
 | 
			
		||||
@ -35,7 +42,7 @@ export const useRightOperate = () => {
 | 
			
		||||
    })
 | 
			
		||||
      .then(async () => {
 | 
			
		||||
        let selectNodes = getSelectedNodes(window.treeObj)
 | 
			
		||||
        const ids = selectNodes.map((item: any) => item.source_id)
 | 
			
		||||
        const ids = selectNodes.map((item: any) => item.id)
 | 
			
		||||
        const res = await TreeApi.removeDirectory({ ids })
 | 
			
		||||
        if (res.code == 0) {
 | 
			
		||||
          ElMessage({
 | 
			
		||||
@ -62,9 +69,48 @@ export const useRightOperate = () => {
 | 
			
		||||
  const pressModel = () => {}
 | 
			
		||||
 | 
			
		||||
  //设置视图
 | 
			
		||||
  const setView = () => {}
 | 
			
		||||
  const setView = () => {
 | 
			
		||||
    let selectNodes = getSelectedNodes(window.treeObj);
 | 
			
		||||
    if(selectNodes && selectNodes[selectNodes.length-1]) {
 | 
			
		||||
      let node = selectNodes[selectNodes.length-1]
 | 
			
		||||
      let params = JSON.parse(node.params)
 | 
			
		||||
      let entityObject = window.earth.entityMap.get(params.id)
 | 
			
		||||
      entityObject.setCustomView()
 | 
			
		||||
      params.customView = entityObject.customView
 | 
			
		||||
      let params2 = {
 | 
			
		||||
        "id": node.id,
 | 
			
		||||
        "sourceName": params.name,
 | 
			
		||||
        // "sourceType": node.sourceType,
 | 
			
		||||
        "parentId": node.parentId,
 | 
			
		||||
        "treeIndex": node.treeIndex,
 | 
			
		||||
        "params": params,
 | 
			
		||||
        "isShow": node.isShow ? 1 : 0,
 | 
			
		||||
      }
 | 
			
		||||
      TreeApi.updateDirectoryInfo(params2)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //重置视图
 | 
			
		||||
  const resetView = () => {}
 | 
			
		||||
  const resetView = () => {
 | 
			
		||||
    let selectNodes = getSelectedNodes(window.treeObj);
 | 
			
		||||
    if(selectNodes && selectNodes[selectNodes.length-1]) {
 | 
			
		||||
      let node = selectNodes[selectNodes.length-1]
 | 
			
		||||
      let params = JSON.parse(node.params)
 | 
			
		||||
      let entityObject = window.earth.entityMap.get(params.id)
 | 
			
		||||
      entityObject.resetCustomView()
 | 
			
		||||
      params.customView = entityObject.customView
 | 
			
		||||
      let params2 = {
 | 
			
		||||
        "id": node.id,
 | 
			
		||||
        "sourceName": params.name,
 | 
			
		||||
        // "sourceType": node.sourceType,
 | 
			
		||||
        // "parentId": node.parentId,
 | 
			
		||||
        // "treeIndex": node.treeIndex,
 | 
			
		||||
        "params": params,
 | 
			
		||||
        "isShow": node.isShow ? 1 : 0,
 | 
			
		||||
      }
 | 
			
		||||
      TreeApi.updateDirectoryInfo(params2)
 | 
			
		||||
      cusUpdateNode({"id": params2.id, "sourceName": params2.sourceName, "params": JSON.stringify(params)})
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //提升图层
 | 
			
		||||
  const layerRaise = () => {}
 | 
			
		||||
  //降低图层
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
        <div
 | 
			
		||||
          v-for="item in menus"
 | 
			
		||||
          class="itemBox"
 | 
			
		||||
          @click="itemClick(item)"
 | 
			
		||||
          @click="itemClick(item, eventBus)"
 | 
			
		||||
          @mouseup="$changeComponentShow('#rMenu', false)"
 | 
			
		||||
        >
 | 
			
		||||
          <div class="itemIcon">
 | 
			
		||||
@ -32,6 +32,8 @@ import { useRightOperate } from './hooks/rightOperate'
 | 
			
		||||
import { useRightMenu } from './hooks/rightMenu'
 | 
			
		||||
 | 
			
		||||
import { getIP } from '@/utils'
 | 
			
		||||
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
const { rightMenus } = useRightOperate()
 | 
			
		||||
const { itemClick } = useRightMenu()
 | 
			
		||||
 | 
			
		||||
@ -40,6 +42,7 @@ const rightClickTreeNode: any = ref()
 | 
			
		||||
// 初始化菜单
 | 
			
		||||
const initMenus = (arr: any, treeNode: any) => {
 | 
			
		||||
  let rightMenu: any = []
 | 
			
		||||
  console.log('rightMenu2222', rightMenu)
 | 
			
		||||
  if (treeNode) {
 | 
			
		||||
    rightClickTreeNode.value = treeNode
 | 
			
		||||
    arr.forEach((menuId: any) => {
 | 
			
		||||
@ -52,6 +55,7 @@ const initMenus = (arr: any, treeNode: any) => {
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  } else rightMenu = [rightMenus.addDirectory]
 | 
			
		||||
  console.log('rightMenu', rightMenu)
 | 
			
		||||
  menus.value = rightMenu
 | 
			
		||||
}
 | 
			
		||||
// 暴露方法给父组件
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import { $changeComponentShow } from '@/utils/communication'
 | 
			
		||||
import { useTreeNode } from './treeNode'
 | 
			
		||||
import { TreeApi } from '@/api/tree'
 | 
			
		||||
import { initMapData } from '../initMapData'
 | 
			
		||||
 | 
			
		||||
export const useTree = () => {
 | 
			
		||||
  const rightMenuRef: any = ref() //右键菜单的实例
 | 
			
		||||
@ -24,10 +25,10 @@ export const useTree = () => {
 | 
			
		||||
      if (isCtrl) {
 | 
			
		||||
        let isSelected = window.treeObj
 | 
			
		||||
          .getSelectedNodes()
 | 
			
		||||
          .some((node: any) => node.source_id === treeNode.source_id)
 | 
			
		||||
          .some((node: any) => node.id === treeNode.id)
 | 
			
		||||
        if (isSelected) {
 | 
			
		||||
          // 如果节点已选中,则取消选中
 | 
			
		||||
          nodes.value = nodes.value.filter((node: any) => node.source_id !== treeNode.source_id)
 | 
			
		||||
          nodes.value = nodes.value.filter((node: any) => node.id !== treeNode.id)
 | 
			
		||||
        } else {
 | 
			
		||||
          // 如果节点未选中,则添加到选中列表
 | 
			
		||||
          nodes.value.push(treeNode)
 | 
			
		||||
@ -48,11 +49,12 @@ export const useTree = () => {
 | 
			
		||||
    let selectNodes = getSelectedNodes(treeObj.value)
 | 
			
		||||
    let isnewSelect = true //是否为新选中
 | 
			
		||||
    selectNodes.forEach((item: any) => {
 | 
			
		||||
      if (treeNode && item.source_id == treeNode.source_id) isnewSelect = false
 | 
			
		||||
      if (treeNode && item.id == treeNode.id) isnewSelect = false
 | 
			
		||||
    })
 | 
			
		||||
    if (!event.ctrlKey && (selectNodes.length < 2 || isnewSelect))
 | 
			
		||||
      cusSelectNode(treeObj.value, treeNode)
 | 
			
		||||
    const menus = showRightMenu(event, treeObj.value)
 | 
			
		||||
    console.log('menus', menus)
 | 
			
		||||
    if (menus.length == 0) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
@ -60,6 +62,16 @@ export const useTree = () => {
 | 
			
		||||
      rightMenuRef.value.initMenus(menus, treeNode)
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * 树形节点左键双击
 | 
			
		||||
   * @param event 事件对象
 | 
			
		||||
   * @param treeId 树形结构id
 | 
			
		||||
   * @param treeNode 鼠标右键点击时所在节点的 JSON 数据对象
 | 
			
		||||
   */
 | 
			
		||||
  const onDblClick = (event: MouseEvent, treeId: string, treeNode: any) => {
 | 
			
		||||
    let entityObject = window.earth.entityMap.get(treeNode.id)
 | 
			
		||||
    entityObject.flyTo()
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * 用于捕获节点拖拽操作结束的事件回调函数
 | 
			
		||||
   * @param event 事件对象
 | 
			
		||||
@ -87,9 +99,9 @@ export const useTree = () => {
 | 
			
		||||
    })
 | 
			
		||||
    const list = newNode.map((item: any) => {
 | 
			
		||||
      return {
 | 
			
		||||
        source_id: item.source_id,
 | 
			
		||||
        id: item.id,
 | 
			
		||||
        tree_index: item.tree_index,
 | 
			
		||||
        p_id: item.p_id
 | 
			
		||||
        parentId: item.parentId
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    const res = await TreeApi.updateTree({ list })
 | 
			
		||||
@ -109,11 +121,11 @@ export const useTree = () => {
 | 
			
		||||
    // let nodes = this.treeObj.getSelectedNodes();
 | 
			
		||||
    // let source_ids = [];
 | 
			
		||||
    // nodes.forEach((item) => {
 | 
			
		||||
    //   source_ids.push(item.source_id);
 | 
			
		||||
    //   source_ids.push(item.id);
 | 
			
		||||
    // });
 | 
			
		||||
    // let updateTree = (nodes, p_id) => {
 | 
			
		||||
    // let updateTree = (nodes, parentId) => {
 | 
			
		||||
    //   nodes.forEach((item) => {
 | 
			
		||||
    //     item.p_id = p_id;
 | 
			
		||||
    //     item.parentId = parentId;
 | 
			
		||||
    //     this.treeObj.updateNode(item);
 | 
			
		||||
    //   });
 | 
			
		||||
    // };
 | 
			
		||||
@ -123,10 +135,10 @@ export const useTree = () => {
 | 
			
		||||
    //   updatePid(
 | 
			
		||||
    //     {
 | 
			
		||||
    //       source_ids,
 | 
			
		||||
    //       p_id: "",
 | 
			
		||||
    //       parentId: "",
 | 
			
		||||
    //       trees: [
 | 
			
		||||
    //         {
 | 
			
		||||
    //           source_id: treeNodes[0].source_id,
 | 
			
		||||
    //           id: treeNodes[0].id,
 | 
			
		||||
    //           tree_index: treeNodes[0].getIndex(),
 | 
			
		||||
    //         },
 | 
			
		||||
    //       ],
 | 
			
		||||
@ -146,18 +158,18 @@ export const useTree = () => {
 | 
			
		||||
    //   let trees = [];
 | 
			
		||||
    //   Nodes.forEach((item) => {
 | 
			
		||||
    //     trees.push({
 | 
			
		||||
    //       source_id: item.source_id,
 | 
			
		||||
    //       id: item.id,
 | 
			
		||||
    //       tree_index: item.getIndex(),
 | 
			
		||||
    //     });
 | 
			
		||||
    //   });
 | 
			
		||||
    //   let p_id = ["prev", "next"].includes(moveType)
 | 
			
		||||
    //     ? targetNode.p_id
 | 
			
		||||
    //     : targetNode.source_id;
 | 
			
		||||
    //   if (p_id == "") {
 | 
			
		||||
    //     p_id = -1;
 | 
			
		||||
    //   let parentId = ["prev", "next"].includes(moveType)
 | 
			
		||||
    //     ? targetNode.parentId
 | 
			
		||||
    //     : targetNode.id;
 | 
			
		||||
    //   if (parentId == "") {
 | 
			
		||||
    //     parentId = -1;
 | 
			
		||||
    //   }
 | 
			
		||||
    //   console.log("p_id", this.treeObj.getSelectedNodes());
 | 
			
		||||
    //   updatePid({ source_ids, p_id, trees }, (res) => {
 | 
			
		||||
    //   console.log("parentId", this.treeObj.getSelectedNodes());
 | 
			
		||||
    //   updatePid({ source_ids, parentId, trees }, (res) => {
 | 
			
		||||
    //     console.log(res);
 | 
			
		||||
    //   });
 | 
			
		||||
    // }
 | 
			
		||||
@ -182,16 +194,16 @@ export const useTree = () => {
 | 
			
		||||
 | 
			
		||||
    // if (
 | 
			
		||||
    //   ['prev', 'next', 'inner'].includes(moveType) &&
 | 
			
		||||
    //   ['pressModel', 'terrainDig'].includes(treeNodes[0].source_type)
 | 
			
		||||
    //   ['pressModel', 'terrainDig'].includes(treeNodes[0].sourceType)
 | 
			
		||||
    // ) {
 | 
			
		||||
    //   return false
 | 
			
		||||
    // }
 | 
			
		||||
    // if (['prev', 'next'].includes(moveType)) {
 | 
			
		||||
    //   let parent = this.treeObj.getNodeByParam('source_id', targetNode.p_id, null)
 | 
			
		||||
    //   if (parent && !treeNodeOption.nodeType[parent.source_type].allowChildren) return false
 | 
			
		||||
    //   let parent = this.treeObj.getNodeByParam('id', targetNode.parentId, null)
 | 
			
		||||
    //   if (parent && !treeNodeOption.nodeType[parent.sourceType].allowChildren) return false
 | 
			
		||||
    // }
 | 
			
		||||
    // if (targetNode) {
 | 
			
		||||
    //   if (moveType == 'inner' && !treeNodeOption.nodeType[targetNode.source_type].allowChildren) {
 | 
			
		||||
    //   if (moveType == 'inner' && !treeNodeOption.nodeType[targetNode.sourceType].allowChildren) {
 | 
			
		||||
    //     return false
 | 
			
		||||
    //   }
 | 
			
		||||
    // }
 | 
			
		||||
@ -203,56 +215,51 @@ export const useTree = () => {
 | 
			
		||||
   * @param treeNode
 | 
			
		||||
   */
 | 
			
		||||
  const onCheck = async (event: any, treeId: any, treeNode: any) => {
 | 
			
		||||
    const res = await TreeApi.updateTreeShow({
 | 
			
		||||
      ids: [treeNode.source_id],
 | 
			
		||||
      show: treeNode.is_show
 | 
			
		||||
    })
 | 
			
		||||
    if (res.code == 0) {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '操作成功',
 | 
			
		||||
        type: 'success'
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      ElMessage({
 | 
			
		||||
        message: '操作失败',
 | 
			
		||||
        type: 'error'
 | 
			
		||||
      })
 | 
			
		||||
    let params = JSON.parse(treeNode.params)
 | 
			
		||||
    let entityObject = window.earth.entityMap.get(params.id)
 | 
			
		||||
    entityObject.show = treeNode.isShow
 | 
			
		||||
    params.show = treeNode.isShow
 | 
			
		||||
    let params2 = {
 | 
			
		||||
      "id": treeNode.id,
 | 
			
		||||
      "params": params,
 | 
			
		||||
      "isShow": treeNode.isShow ? 1 : 0,
 | 
			
		||||
    }
 | 
			
		||||
    TreeApi.updateDirectoryInfo(params2)
 | 
			
		||||
 | 
			
		||||
    //   let source_ids = [];
 | 
			
		||||
    //   nodes.forEach((item) => {
 | 
			
		||||
    //     if (item.isHidden == false) {
 | 
			
		||||
    //       source_ids.push(item.source_id);
 | 
			
		||||
    //       source_ids.push(item.id);
 | 
			
		||||
    //     }
 | 
			
		||||
    //   });
 | 
			
		||||
    //   //根据source_id获取对应的资源更改其在地球上的显示状态
 | 
			
		||||
    //   let sourceStatus = (source_ids, status) => {
 | 
			
		||||
    //     source_ids.forEach((id) => {
 | 
			
		||||
    //       // let node1 = this.treeObj.getNodeByParam("source_id", id, null);
 | 
			
		||||
    //       // let node1 = this.treeObj.getNodeByParam("id", id, null);
 | 
			
		||||
    //       // console.log("ddddddddddddddddddddddd", id, node1);
 | 
			
		||||
    //       // let source1 = window._entityMap.get(id);
 | 
			
		||||
    //       // console.log("source1", source1);
 | 
			
		||||
    //       // return;
 | 
			
		||||
    //       let source = window._entityMap.get(id);
 | 
			
		||||
    //       let node = this.treeObj.getNodeByParam("source_id", id, null);
 | 
			
		||||
    //       let node = this.treeObj.getNodeByParam("id", id, null);
 | 
			
		||||
    //       console.log("source", source, node);
 | 
			
		||||
    //       node.source_name = node.oldname || node.source_name;
 | 
			
		||||
    //       if (node.source_type == "Feature") {
 | 
			
		||||
    //       node.sourceName = node.oldname || node.sourceName;
 | 
			
		||||
    //       if (node.sourceType == "Feature") {
 | 
			
		||||
    //         let shp = window._entityMap.get(node.fid);
 | 
			
		||||
    //         shp.setShow(status, id);
 | 
			
		||||
    //         return;
 | 
			
		||||
    //       }
 | 
			
		||||
    //       if (node.source_type == "FeatureCollection") {
 | 
			
		||||
    //       if (node.sourceType == "FeatureCollection") {
 | 
			
		||||
    //         let shp = window._entityMap.get(node.fid);
 | 
			
		||||
    //         console.log("shp", shp);
 | 
			
		||||
    //         node.children.forEach((item) => {
 | 
			
		||||
    //           shp.setShow(status, item.source_id);
 | 
			
		||||
    //           shp.setShow(status, item.id);
 | 
			
		||||
    //           console.log("item", status, item);
 | 
			
		||||
    //         });
 | 
			
		||||
    //         return;
 | 
			
		||||
    //       }
 | 
			
		||||
    //       if (["kml", "gdb", "shp"].includes(node.source_type)) {
 | 
			
		||||
    //         let entity = window._entityMap.get(node.source_id);
 | 
			
		||||
    //       if (["kml", "gdb", "shp"].includes(node.sourceType)) {
 | 
			
		||||
    //         let entity = window._entityMap.get(node.id);
 | 
			
		||||
    //         if (entity) {
 | 
			
		||||
    //           entity.show = status;
 | 
			
		||||
    //           if (status) {
 | 
			
		||||
@ -260,11 +267,11 @@ export const useTree = () => {
 | 
			
		||||
    //           }
 | 
			
		||||
    //         }
 | 
			
		||||
    //       }
 | 
			
		||||
    //       if (node.source_type == "node" || node.source_type == "element") {
 | 
			
		||||
    //       if (node.sourceType == "node" || node.sourceType == "element") {
 | 
			
		||||
    //         let bim = window._entityMap.get(node.fid);
 | 
			
		||||
    //         bim.featureShow(node.source_id.split("_")[0], status);
 | 
			
		||||
    //         bim.featureShow(node.id.split("_")[0], status);
 | 
			
		||||
    //       }
 | 
			
		||||
    //       if (node.source_type == "roam") {
 | 
			
		||||
    //       if (node.sourceType == "roam") {
 | 
			
		||||
    //         let num;
 | 
			
		||||
    //         if (status) {
 | 
			
		||||
    //           num = Infinity;
 | 
			
		||||
@ -274,9 +281,9 @@ export const useTree = () => {
 | 
			
		||||
    //         node.detail.repeat = num;
 | 
			
		||||
    //         YJ.Global.FlyRoam.setRepeat(num);
 | 
			
		||||
    //       }
 | 
			
		||||
    //       if (window.right_entityMap.get(treeNode.source_id))
 | 
			
		||||
    //         window.right_entityMap.get(treeNode.source_id).show = status;
 | 
			
		||||
    //       if (node.source_type == "path") {
 | 
			
		||||
    //       if (window.right_entityMap.get(treeNode.id))
 | 
			
		||||
    //         window.right_entityMap.get(treeNode.id).show = status;
 | 
			
		||||
    //       if (node.sourceType == "path") {
 | 
			
		||||
    //         let pathModel = window._entityMap.get(id);
 | 
			
		||||
    //         // console.log("pathModel+++++++++++++", pathModel, pathModel.modelShow);
 | 
			
		||||
    //         if (pathModel) {
 | 
			
		||||
@ -293,15 +300,15 @@ export const useTree = () => {
 | 
			
		||||
    //     });
 | 
			
		||||
    //   };
 | 
			
		||||
    //   //调用接口更改数据库is_show的值
 | 
			
		||||
    //   if (treeNode.is_show) {
 | 
			
		||||
    //   if (treeNode.isShow) {
 | 
			
		||||
    //     showSource({ source_ids }, (data) => {
 | 
			
		||||
    //       console.log(data);
 | 
			
		||||
    //       sourceStatus(source_ids, treeNode.is_show);
 | 
			
		||||
    //       sourceStatus(source_ids, treeNode.isShow);
 | 
			
		||||
    //     });
 | 
			
		||||
    //   } else {
 | 
			
		||||
    //     hideSource({ source_ids }, (data) => {
 | 
			
		||||
    //       console.log(data);
 | 
			
		||||
    //       sourceStatus(source_ids, treeNode.is_show);
 | 
			
		||||
    //       sourceStatus(source_ids, treeNode.isShow);
 | 
			
		||||
    //     });
 | 
			
		||||
    //   }
 | 
			
		||||
    //   // YJ.Global.splitScreen.setActiveId([]);
 | 
			
		||||
@ -366,23 +373,24 @@ export const useTree = () => {
 | 
			
		||||
      onClick: onClick,
 | 
			
		||||
      onDrop: onDrop,
 | 
			
		||||
      beforeDrop: beforeDrop,
 | 
			
		||||
      onCheck: onCheck
 | 
			
		||||
      onCheck: onCheck,
 | 
			
		||||
      onDblClick: onDblClick
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 树的数据
 | 
			
		||||
  const zNodes = ref([
 | 
			
		||||
    {
 | 
			
		||||
      source_id: 1,
 | 
			
		||||
      p_id: 0,
 | 
			
		||||
      source_name: '111',
 | 
			
		||||
      is_show: true
 | 
			
		||||
      id: 1,
 | 
			
		||||
      parentId: 0,
 | 
			
		||||
      sourceName: '111',
 | 
			
		||||
      isShow: true
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      source_id: 2,
 | 
			
		||||
      p_id: 0,
 | 
			
		||||
      source_name: '222',
 | 
			
		||||
      is_show: true
 | 
			
		||||
      id: 2,
 | 
			
		||||
      parentId: 0,
 | 
			
		||||
      sourceName: '222',
 | 
			
		||||
      isShow: true
 | 
			
		||||
    }
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
@ -408,12 +416,26 @@ export const useTree = () => {
 | 
			
		||||
      treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value)
 | 
			
		||||
      window.treeObj = treeObj.value
 | 
			
		||||
      window.AllNodes = treeObj.value.getNodes()
 | 
			
		||||
      initTreeCallBack()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const initTreeCallBack = () => {
 | 
			
		||||
    if (window.earth) {
 | 
			
		||||
      for (let i = 0; i < zNodes.value.length; i++) {
 | 
			
		||||
        if (zNodes.value[i].params) {
 | 
			
		||||
          let params = JSON.parse(zNodes.value[i].params)
 | 
			
		||||
          initMapData(zNodes.value[i].sourceType, params)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    initTree,
 | 
			
		||||
    setting,
 | 
			
		||||
    rightMenuRef
 | 
			
		||||
    rightMenuRef,
 | 
			
		||||
    initTreeCallBack
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,12 @@ export const useTreeNode = () => {
 | 
			
		||||
      // detailFun: get_detail_groundImage,
 | 
			
		||||
      // allowChildren: false,
 | 
			
		||||
    },
 | 
			
		||||
    groundSvg: {
 | 
			
		||||
      rightMenus: ['edit', 'del', 'setView', 'resetView']
 | 
			
		||||
      // render: renderGroundImage,
 | 
			
		||||
      // detailFun: get_detail_groundImage,
 | 
			
		||||
      // allowChildren: false,
 | 
			
		||||
    },
 | 
			
		||||
    waterl: {
 | 
			
		||||
      rightMenus: ['edit', 'del', 'setView', 'resetView']
 | 
			
		||||
      // render: renderSpout,
 | 
			
		||||
@ -429,16 +435,16 @@ export const useTreeNode = () => {
 | 
			
		||||
   */
 | 
			
		||||
  const cusAddNodes = (treeObj: any, parentNodeId: any, newNodes: any, isSilent?: any) => {
 | 
			
		||||
    // newNodes.forEach((node: any) => {
 | 
			
		||||
    //   // if (node.source_type != "directory") node.icon = cusNodeIcon(node);
 | 
			
		||||
    //   // if (node.sourceType != "directory") node.icon = cusNodeIcon(node);
 | 
			
		||||
    //   if (node.detail && typeof node.detail == 'string') node.detail = JSON.parse(node.detail)
 | 
			
		||||
    //   // if(node.p_id)
 | 
			
		||||
    //   YJ.Global.splitScreen.setActiveId([node.source_id])
 | 
			
		||||
    //   // if(node.parentId)
 | 
			
		||||
    //   YJ.Global.splitScreen.setActiveId([node.id])
 | 
			
		||||
    // })
 | 
			
		||||
    let parentNode = null
 | 
			
		||||
    if (Object.prototype.toString.call(parentNodeId) === '[object Object]')
 | 
			
		||||
      parentNode = parentNodeId
 | 
			
		||||
    else {
 | 
			
		||||
      parentNode = treeObj.getNodeByParam('source_id', parentNodeId, null)
 | 
			
		||||
      parentNode = treeObj.getNodeByParam('id', parentNodeId, null)
 | 
			
		||||
    }
 | 
			
		||||
    let arr = treeObj.addNodes(parentNode, newNodes, isSilent)
 | 
			
		||||
    treeObj.selectNode(arr[arr.length - 1])
 | 
			
		||||
@ -459,7 +465,7 @@ export const useTreeNode = () => {
 | 
			
		||||
      allNodes = allNodes.concat(treeObj.transformToArray(node))
 | 
			
		||||
    })
 | 
			
		||||
    allNodes.forEach((node: any) => {
 | 
			
		||||
      _idSet.add(node.source_id)
 | 
			
		||||
      _idSet.add(node.id)
 | 
			
		||||
      treeObj.removeNode(node)
 | 
			
		||||
    })
 | 
			
		||||
    // treeObj.getNodes()
 | 
			
		||||
@ -486,6 +492,18 @@ export const useTreeNode = () => {
 | 
			
		||||
    return siblings
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function cusUpdateNode({ id, sourceName, params }) {
 | 
			
		||||
    let node = window.treeObj.getNodeByParam(
 | 
			
		||||
      "id",
 | 
			
		||||
      id,
 | 
			
		||||
      null
 | 
			
		||||
    );
 | 
			
		||||
    node.sourceName = sourceName;
 | 
			
		||||
    node.oldname = sourceName;
 | 
			
		||||
    node.params = params;
 | 
			
		||||
    window.treeObj.updateNode(node);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 显示、定位右键菜单组件并返回菜单数组
 | 
			
		||||
   */
 | 
			
		||||
@ -534,7 +552,7 @@ export const useTreeNode = () => {
 | 
			
		||||
      if (selectedNodes.length == 0) arr = ['addDirectory']
 | 
			
		||||
      else {
 | 
			
		||||
        try {
 | 
			
		||||
          arr = nodeType[selectedNodes[0].source_type].rightMenus
 | 
			
		||||
          arr = nodeType[selectedNodes[0].sourceType].rightMenus
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          arr = []
 | 
			
		||||
        }
 | 
			
		||||
@ -594,6 +612,7 @@ export const useTreeNode = () => {
 | 
			
		||||
    cusAddNodes,
 | 
			
		||||
    getSameLevel,
 | 
			
		||||
    cusRemoveNode,
 | 
			
		||||
    cusUpdateNode,
 | 
			
		||||
    findParentId,
 | 
			
		||||
    findTreeIndex
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -82,7 +82,7 @@ import rightMenu from './components/rightMenu.vue'
 | 
			
		||||
import { $changeComponentShow } from '@/utils/communication'
 | 
			
		||||
import { bus } from '@/utils/bus'
 | 
			
		||||
 | 
			
		||||
const { initTree, rightMenuRef } = useTree()
 | 
			
		||||
const { initTree, rightMenuRef, initTreeCallBack } = useTree()
 | 
			
		||||
 | 
			
		||||
const { t } = useI18n()
 | 
			
		||||
const isShow = ref(false)
 | 
			
		||||
@ -164,6 +164,9 @@ onMounted(() => {
 | 
			
		||||
  //   initTree()
 | 
			
		||||
  // })
 | 
			
		||||
})
 | 
			
		||||
defineExpose({
 | 
			
		||||
  initTreeCallBack
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										42
									
								
								src/renderer/src/views/components/tree/initMapData.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/renderer/src/views/components/tree/initMapData.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
export const initMapData = async (type, data) => {
 | 
			
		||||
  let entityObject
 | 
			
		||||
  let options
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'point':
 | 
			
		||||
      entityObject = new YJ.Obj.BillboardObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'line':
 | 
			
		||||
      entityObject = await new YJ.Obj.PolylineObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'curve':
 | 
			
		||||
      entityObject = await new YJ.Obj.CurvelineObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'polygon':
 | 
			
		||||
      entityObject = new YJ.Obj.PolygonObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'groundText':
 | 
			
		||||
      entityObject = new YJ.Obj.GroundText(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'standText':
 | 
			
		||||
      entityObject = new YJ.Obj.StandText(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'circle':
 | 
			
		||||
      entityObject = new YJ.Obj.CircleObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'rectangle':
 | 
			
		||||
      entityObject = new YJ.Obj.RectangleObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'ellipse':
 | 
			
		||||
      entityObject = new YJ.Obj.EllipseObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    case 'model':
 | 
			
		||||
      entityObject = new YJ.Obj.ModelObject(window.earth, data)
 | 
			
		||||
      break
 | 
			
		||||
    default:
 | 
			
		||||
      return
 | 
			
		||||
      break
 | 
			
		||||
  }
 | 
			
		||||
  options = structuredClone(entityObject.options)
 | 
			
		||||
  delete options.host
 | 
			
		||||
  return options
 | 
			
		||||
}
 | 
			
		||||
@ -2,12 +2,13 @@
 | 
			
		||||
  <Headers></Headers>
 | 
			
		||||
  <div id="earthContainer" class="fullSize"></div>
 | 
			
		||||
  <Tree class="tree" ref="tree"></Tree>
 | 
			
		||||
  <component :is="currentComponent" ref="dynamicComponentRef" />
 | 
			
		||||
  <richText></richText>
 | 
			
		||||
  <addDirectory ref="adddirectoryBox" class="adddirectoryBox absolute zIndex999"></addDirectory>
 | 
			
		||||
  <PropertyDialog ref="baseDialog"></PropertyDialog>
 | 
			
		||||
  <!-- <addStandText ref="addStandTextRef"></addStandText> -->
 | 
			
		||||
  <!--左侧一级菜单-->
 | 
			
		||||
  <firstMenu class="absolute zIndex9" ref="firstMenu"></firstMenu>
 | 
			
		||||
  <firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
 | 
			
		||||
  <!--底部菜单-->
 | 
			
		||||
  <bottomMenu class="absolute zIndex9" ref="bottomMenu"></bottomMenu>
 | 
			
		||||
  <!-- 多点视线分析 -->
 | 
			
		||||
  <Visibility ref="visibility"></Visibility>
 | 
			
		||||
  <CircleViewShed ref="CircleViewShed"></CircleViewShed>
 | 
			
		||||
@ -22,12 +23,22 @@
 | 
			
		||||
  <CoorLocation ref="CoorLocation"></CoorLocation>
 | 
			
		||||
  <ScreenShot ref="ScreenShot"></ScreenShot>
 | 
			
		||||
  <TerrainExcavation ref="TerrainExcavation"></TerrainExcavation>
 | 
			
		||||
  <bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
 | 
			
		||||
  <input type="file" id="fileInputlink" style="display: none;" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf"
 | 
			
		||||
    @input="uploadFile">
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { inject, shallowRef, ref } from "vue";
 | 
			
		||||
import Headers from '../components/headers/index.vue'
 | 
			
		||||
import Tree from '../components/tree/index.vue'
 | 
			
		||||
import PropertyDialog from '../components/propertyBox/standText.vue'
 | 
			
		||||
import addStandText from '../components/propertyBox/addStandText.vue'
 | 
			
		||||
import addGroundText from '../components/propertyBox/addGroundText.vue'
 | 
			
		||||
import billboardObject from '../components/propertyBox/billboardObject.vue'
 | 
			
		||||
import polygonObject from '../components/propertyBox/polygonObject.vue'
 | 
			
		||||
import polylineObject from '../components/propertyBox/polylineObject.vue'
 | 
			
		||||
import curvelineObject from '../components/propertyBox/curvelineObject.vue'
 | 
			
		||||
import richText from '../components/propertyBox/richText.vue'
 | 
			
		||||
import addDirectory from '@/components/dialog/directory.vue'
 | 
			
		||||
import firstMenu from '@/views/components/leftSide/leftSideFirst.vue'
 | 
			
		||||
import bottomMenu from '@/views/components/bottomSide/bottomSide.vue'
 | 
			
		||||
@ -44,9 +55,70 @@ 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'
 | 
			
		||||
 | 
			
		||||
const createEarth = () => {
 | 
			
		||||
  window.earth = new YJ.YJEarth('earthContainer')
 | 
			
		||||
const firstMenuRef = ref(null)
 | 
			
		||||
const bottomMenuRef = ref(null)
 | 
			
		||||
const eventBus = inject("bus");
 | 
			
		||||
let currentComponent = shallowRef()
 | 
			
		||||
let dynamicComponentRef = ref()
 | 
			
		||||
let addStandTextRef = ref()
 | 
			
		||||
let tree = ref()
 | 
			
		||||
eventBus.on("openDialog", async (sourceType: any, id: any) => {
 | 
			
		||||
  switch (sourceType) {
 | 
			
		||||
    case 'groundText':
 | 
			
		||||
      currentComponent.value = addGroundText
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open()
 | 
			
		||||
      break;
 | 
			
		||||
    case 'standText':
 | 
			
		||||
      currentComponent.value = addStandText
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open()
 | 
			
		||||
      break;
 | 
			
		||||
    case 'point':
 | 
			
		||||
      currentComponent.value = billboardObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open(id)
 | 
			
		||||
      break;
 | 
			
		||||
    case 'line':
 | 
			
		||||
      currentComponent.value = polylineObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open(id)
 | 
			
		||||
      break;
 | 
			
		||||
    case 'curve':
 | 
			
		||||
      currentComponent.value = curvelineObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open(id)
 | 
			
		||||
      break;
 | 
			
		||||
      break;
 | 
			
		||||
    case 'panel':
 | 
			
		||||
      currentComponent.value = polygonObject
 | 
			
		||||
      await nextTick()
 | 
			
		||||
      dynamicComponentRef.value?.open(id)
 | 
			
		||||
      break;
 | 
			
		||||
    case 'circle':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'rectangle':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'rendezvous':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'attackArrow':
 | 
			
		||||
      break;
 | 
			
		||||
    case 'pincerArrow':
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
eventBus.on("destroyComponent",()=>{
 | 
			
		||||
  currentComponent.value = undefined
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const createEarth = async () => {
 | 
			
		||||
  window.earth = await new YJ.YJEarth('earthContainer')
 | 
			
		||||
  tree.value.initTreeCallBack()
 | 
			
		||||
  // YJ.Global.setDefaultView(window.earth, {
 | 
			
		||||
  //   destination: { lng: 100, lat: 30, alt: 10 },
 | 
			
		||||
  //   orientation: {
 | 
			
		||||
@ -58,6 +130,34 @@ const createEarth = () => {
 | 
			
		||||
  // new YJ.Tools(window.earth).flyHome(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let clickAddLinkCb
 | 
			
		||||
 | 
			
		||||
eventBus.on('defineClickAddLinkCb', (fun) => {
 | 
			
		||||
  clickAddLinkCb = fun
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const uploadFile = (event) => {
 | 
			
		||||
  let files = event.target.files
 | 
			
		||||
  if (files.length > 0) {
 | 
			
		||||
    const formData = new FormData();
 | 
			
		||||
    for (let i = 0; i < files.length; i++) {
 | 
			
		||||
      const element = files[i];
 | 
			
		||||
      formData.append('files', element);
 | 
			
		||||
    }
 | 
			
		||||
    GisApi.linkFile(formData).then(res => {
 | 
			
		||||
      if (res.code == 0 || res.code == 200) {
 | 
			
		||||
        ElMessage({
 | 
			
		||||
          message: '上传成功',
 | 
			
		||||
          type: 'success'
 | 
			
		||||
        })
 | 
			
		||||
        // this.$sendChanel("linkFileData", res.data);
 | 
			
		||||
        clickAddLinkCb && clickAddLinkCb(res.data)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
onMounted(async () => {
 | 
			
		||||
  await YJ.on()
 | 
			
		||||
  createEarth()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user