Merge branch 'zyl' of http://xny.yj-3d.com:3000/zhouyulong/electron-4 into zyl
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -4,5 +4,6 @@ build | |||||||
| out | out | ||||||
| .history | .history | ||||||
| .DS_Store | .DS_Store | ||||||
|  | .vscode | ||||||
| .eslintcache | .eslintcache | ||||||
| *.log* | *.log* | ||||||
|  | |||||||
							
								
								
									
										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'] |     ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | ||||||
|     ElTabPane: typeof import('element-plus/es')['ElTabPane'] |     ElTabPane: typeof import('element-plus/es')['ElTabPane'] | ||||||
|     ElTabs: typeof import('element-plus/es')['ElTabs'] |     ElTabs: typeof import('element-plus/es')['ElTabs'] | ||||||
|  |     ElTag: typeof import('element-plus/es')['ElTag'] | ||||||
|     ElUpload: typeof import('element-plus/es')['ElUpload'] |     ElUpload: typeof import('element-plus/es')['ElUpload'] | ||||||
|     Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default'] |     Index_b: typeof import('./src/components/SvgIcon/index_b.vue')['default'] | ||||||
|     Pagination: typeof import('./src/components/Pagination/index.vue')['default'] |     Pagination: typeof import('./src/components/Pagination/index.vue')['default'] | ||||||
|  | |||||||
| @ -65,7 +65,7 @@ | |||||||
|   position: absolute; |   position: absolute; | ||||||
|   color: var(--color-sdk-auxiliary-public); |   color: var(--color-sdk-auxiliary-public); | ||||||
|   font-size: 14px; |   font-size: 14px; | ||||||
|   z-index: 999999; |   z-index: 99; | ||||||
|   background: linear-gradient(0deg, var(--color-sdk-bg-gradual)), rgba(0, 0, 0, 0.6); |   background: linear-gradient(0deg, var(--color-sdk-bg-gradual)), rgba(0, 0, 0, 0.6); | ||||||
|   border: 1.5px solid; |   border: 1.5px solid; | ||||||
|   border-image: linear-gradient(to bottom, var(--color-sdk-gradual)) 1; |   border-image: linear-gradient(to bottom, var(--color-sdk-gradual)) 1; | ||||||
| @ -76,8 +76,6 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| .YJ-custom-base-dialog * { | .YJ-custom-base-dialog * { | ||||||
|   margin: 0px; |  | ||||||
|   padding: 0px; |  | ||||||
|   box-sizing: border-box; |   box-sizing: border-box; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -171,7 +169,7 @@ | |||||||
|   position: relative; |   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; |   border-color: rgba(var(--color-sdk-base-rgb), 1) !important; | ||||||
|   cursor: pointer; |   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 = []; |     let notSearchTypeNodesIds = []; | ||||||
|     if (notSearchType.length) { |     if (notSearchType.length) { | ||||||
|       allNodes.forEach((allNodeItem) => { |       allNodes.forEach((allNodeItem) => { | ||||||
|         if (notSearchType.includes(allNodeItem.source_type)) { |         if (notSearchType.includes(allNodeItem.sourceType)) { | ||||||
|           notSearchTypeNodesIds.push(allNodeItem[idKey]); |           notSearchTypeNodesIds.push(allNodeItem[idKey]); | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
| @ -81,19 +81,19 @@ window.newFuzzySearch = function( | |||||||
|     hideAllNode(allNodes); |     hideAllNode(allNodes); | ||||||
|     nodeChildren.forEach((item) => { |     nodeChildren.forEach((item) => { | ||||||
|       if (item.oldname) { |       if (item.oldname) { | ||||||
|         item.source_name = item.oldname; |         item.sourceName = item.oldname; | ||||||
|         zTreeObj.updateNode(item); |         zTreeObj.updateNode(item); | ||||||
|       } |       } | ||||||
|       if (contrast) { |       if (contrast) { | ||||||
|         if ((item.source_name || "").indexOf(contrast) > -1) { |         if ((item.sourceName || "").indexOf(contrast) > -1) { | ||||||
|           console.log("source_name包含关键字"); |           console.log("sourceName包含关键字"); | ||||||
|           console.log(item); |           console.log(item); | ||||||
|           console.log(item.source_name); |           console.log(item.sourceName); | ||||||
|  |  | ||||||
|           item.oldname = item.source_name; |           item.oldname = item.sourceName; | ||||||
|           item.highlight = true; |           item.highlight = true; | ||||||
|           let F = new RegExp(contrast, "gi"); |           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 = |             let str = | ||||||
|               '<span style="color: whitesmoke;background-color: darkred;">' + |               '<span style="color: whitesmoke;background-color: darkred;">' + | ||||||
|               h + |               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 () => { |   getTreeList: async () => { | ||||||
|     return await request.get({ |     return await request.get({ | ||||||
|       url: `/source/list` |       url: `/source/list` | ||||||
|       // url: `/yjearth4/api/v1/source/list` |  | ||||||
|     }) |     }) | ||||||
|   }, |   }, | ||||||
|   // 新增其他资源  /source/addOtherSource |   // 新增其他资源  /source/addOtherSource | ||||||
| @ -19,9 +18,26 @@ export const TreeApi = { | |||||||
|   //新增节点 |   //新增节点 | ||||||
|   addDirectory: async (data: any) => { |   addDirectory: async (data: any) => { | ||||||
|     return await request.post({ |     return await request.post({ | ||||||
|       url: `/yjearth4/api/v1/directory/add`, |       url: `/source/addOtherSource`, | ||||||
|       data |       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) => { |   removeDirectory: async (data: any) => { | ||||||
|  | |||||||
| @ -293,7 +293,6 @@ img { | |||||||
|   background-color: rgba(0, 0, 0, 0.5) !important; |   background-color: rgba(0, 0, 0, 0.5) !important; | ||||||
|   border: none !important; /* 去除边框 */ |   border: none !important; /* 去除边框 */ | ||||||
|   box-shadow: none !important; /* 去除阴影 */ |   box-shadow: none !important; /* 去除阴影 */ | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| .el-select-dropdown__item { | .el-select-dropdown__item { | ||||||
|  | |||||||
| @ -1,11 +1,9 @@ | |||||||
| <template> | <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, |       width: width, | ||||||
|       height: height, |       height: height, | ||||||
|       top: top, |  | ||||||
|       left: left, |  | ||||||
|       position: fix ? 'fixed' : 'absolute' |       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" |     <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> |         @click="close"><span class="close"></span><i>✕</i></span></div> | ||||||
|     <div class="content" style="padding: 0 24px 0 24px;"> |     <div class="content" style="padding: 0 24px 0 24px;"> | ||||||
| @ -112,6 +110,7 @@ onMounted(() => { | |||||||
| const open = (data) => { | const open = (data) => { | ||||||
|   if (!first.value) { |   if (!first.value) { | ||||||
|     first.value = true; |     first.value = true; | ||||||
|  |     dialogVisible.value = true; | ||||||
|     nextTick(() => { |     nextTick(() => { | ||||||
|       moveDiv(); |       moveDiv(); | ||||||
|     }); |     }); | ||||||
| @ -131,6 +130,7 @@ const close = () => { | |||||||
|     window.mapService?.removeAnimation(); |     window.mapService?.removeAnimation(); | ||||||
|   } |   } | ||||||
|   callback.value && callback.value(); |   callback.value && callback.value(); | ||||||
|  |  | ||||||
|   props.closeCallback && props.closeCallback() |   props.closeCallback && props.closeCallback() | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @ -142,8 +142,8 @@ const moveDiv = () => { | |||||||
|  |  | ||||||
|   const oClickDiv = baseDialog.value; |   const oClickDiv = baseDialog.value; | ||||||
|   const oMoveDiv = titleBox.value; |   const oMoveDiv = titleBox.value; | ||||||
|  |  | ||||||
|   if (oClickDiv) { |   if (oClickDiv) { | ||||||
|  |     console.log(oMoveDiv) | ||||||
|     oMoveDiv.onmousedown = (e) => { |     oMoveDiv.onmousedown = (e) => { | ||||||
|       // 获取对话框尺寸 |       // 获取对话框尺寸 | ||||||
|       const oMoveDivHeight = baseDialog.value.offsetHeight; |       const oMoveDivHeight = baseDialog.value.offsetHeight; | ||||||
| @ -260,5 +260,25 @@ defineExpose({ | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="scss" scoped> | <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> | </style> | ||||||
|  | |||||||
| @ -17,9 +17,9 @@ | |||||||
|           label-width="80px" |           label-width="80px" | ||||||
|           @keyup.enter.native="submitForm(ruleForm)" |           @keyup.enter.native="submitForm(ruleForm)" | ||||||
|         > |         > | ||||||
|           <el-form-item label="名称:" prop="source_name"> |           <el-form-item label="名称:" prop="sourceName"> | ||||||
|             <!-- @input="removeSpaces" --> |             <!-- @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> | ||||||
|           <el-form-item> |           <el-form-item> | ||||||
|             <div class="btnOption"> |             <div class="btnOption"> | ||||||
| @ -42,14 +42,14 @@ import { useTreeNode } from '@/views/components/tree/hooks/treeNode' | |||||||
| const { getKeyOfSelectedNode, getSelectedNode, cusAddNodes, getSameLevel } = useTreeNode() | const { getKeyOfSelectedNode, getSelectedNode, cusAddNodes, getSameLevel } = useTreeNode() | ||||||
| const title = ref('添加文件夹') | const title = ref('添加文件夹') | ||||||
| let form: any = reactive({ | let form: any = reactive({ | ||||||
|   source_name: '图层' |   sourceName: '图层' | ||||||
| }) | }) | ||||||
| const ruleForm = ref() | const ruleForm = ref() | ||||||
| const rules = reactive({ | const rules = reactive({ | ||||||
|   source_name: [{ required: true, message: '请输入名称', trigger: 'blur' }] |   sourceName: [{ required: true, message: '请输入名称', trigger: 'blur' }] | ||||||
| }) | }) | ||||||
| const removeSpaces = (value: string) => { | const removeSpaces = (value: string) => { | ||||||
|   form.source_name = value.replace(/\s/g, '') |   form.sourceName = value.replace(/\s/g, '') | ||||||
| } | } | ||||||
| const close = () => { | const close = () => { | ||||||
|   $changeComponentPop('.adddirectory', false) |   $changeComponentPop('.adddirectory', false) | ||||||
| @ -65,11 +65,11 @@ const submitForm = async (formEl: FormInstance | undefined) => { | |||||||
|   }) |   }) | ||||||
| } | } | ||||||
| const add = throttle(async () => { | const add = throttle(async () => { | ||||||
|   let p_id = getKeyOfSelectedNode(window.treeObj, 'source_id') |   let parentId = getKeyOfSelectedNode(window.treeObj, 'id') | ||||||
|   let fnone = getSelectedNode(window.treeObj) |   let fnone = getSelectedNode(window.treeObj) | ||||||
|   const res = await TreeApi.addDirectory({ |   const res = await TreeApi.addDirectory({ | ||||||
|     source_name: form.source_name, |     sourceName: form.sourceName, | ||||||
|     p_id |     parentId | ||||||
|   }) |   }) | ||||||
|   if (res.code == 0) { |   if (res.code == 0) { | ||||||
|     const node = { |     const node = { | ||||||
| @ -99,9 +99,9 @@ const add = throttle(async () => { | |||||||
| const updateTree = async (newNode: any) => { | const updateTree = async (newNode: any) => { | ||||||
|   const list = newNode.map((item: any) => { |   const list = newNode.map((item: any) => { | ||||||
|     return { |     return { | ||||||
|       source_id: item.source_id, |       id: item.id, | ||||||
|       tree_index: item.tree_index, |       tree_index: item.tree_index, | ||||||
|       p_id: item.p_id |       parentId: item.parentId | ||||||
|     } |     } | ||||||
|   }) |   }) | ||||||
|   console.log(list) |   console.log(list) | ||||||
| @ -123,7 +123,7 @@ const updateTree = async (newNode: any) => { | |||||||
|  |  | ||||||
| const cancel = () => { | const cancel = () => { | ||||||
|   $changeComponentPop('.adddirectory', false) |   $changeComponentPop('.adddirectory', false) | ||||||
|   form.source_name = '图层' |   form.sourceName = '图层' | ||||||
|   ruleForm.value?.resetFields() |   ruleForm.value?.resetFields() | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -1,16 +1,11 @@ | |||||||
| <template> | <template> | ||||||
|   <div class="bottomMenuBox zIndex9"> |   <div class="bottomMenuBox zIndex9"> | ||||||
|     <div class="animate__animated bottomMenu"> |     <div class="animate__animated bottomMenu"> | ||||||
|       <div |       <div class="bottom_box" v-for="(item, i) of bottomMenuList" :key="i" :title="t('bottomMenu.' + item.sourceType)" | ||||||
|         class="bottom_box" |         @click="addMarker(item)"> | ||||||
|         v-for="(item, i) of bottomMenuList" |         <svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon> | ||||||
|         :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="span"> |         <div class="span"> | ||||||
|           {{ t('bottomMenu.' + item.source_type) }} |           {{ t('bottomMenu.' + item.sourceType) }} | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| @ -21,6 +16,8 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { useI18n } from 'vue-i18n' | import { useI18n } from 'vue-i18n' | ||||||
| import { inject } from "vue"; | import { inject } from "vue"; | ||||||
|  | import { TreeApi } from '@/api/tree' | ||||||
|  | import { initMapData } from '../tree/initMapData' | ||||||
| const { t } = useI18n() | const { t } = useI18n() | ||||||
| const eventBus = inject("bus"); | const eventBus = inject("bus"); | ||||||
|  |  | ||||||
| @ -40,76 +37,178 @@ onMounted(() => { | |||||||
| }) | }) | ||||||
| const bottomMenuList = ref([ | const bottomMenuList = ref([ | ||||||
|   { |   { | ||||||
|     source_name: '贴地文字', |     sourceName: '贴地文字', | ||||||
|     key: 'groundText', |     key: 'groundText', | ||||||
|     source_type: 'groundText', |     sourceType: 'groundText', | ||||||
|     className: 'public' |     className: 'public', | ||||||
|  |     fun: () => { | ||||||
|  |       eventBus.emit("openDialog", 'groundText'); | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     source_name: '立体文字', |     sourceName: '立体文字', | ||||||
|     key: 'standText', |     key: 'standText', | ||||||
|     source_type: 'standText', |     sourceType: 'standText', | ||||||
|     className: 'public' |     className: 'public', | ||||||
|  |     fun: () => { | ||||||
|  |       eventBus.emit("openDialog", 'standText'); | ||||||
|  |     } | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     source_name: '点标注', |     sourceName: '点标注', | ||||||
|     key: 'DrawPoint', |     key: 'DrawPoint', | ||||||
|     source_type: 'point', |     sourceType: 'point', | ||||||
|     className: 'public' |     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', |     key: 'DrawPolyline', | ||||||
|     source_type: 'line', |     sourceType: 'line', | ||||||
|     className: 'public' |     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', |     key: 'DrawPolyline', | ||||||
|     source_type: 'curve', |     sourceType: 'curve', | ||||||
|     className: 'public' |     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', |     key: 'DrawPolygon', | ||||||
|     source_type: 'panel', |     sourceType: 'panel', | ||||||
|     className: 'public' |     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', |     key: 'DrawCircle', | ||||||
|     source_type: 'circle', |     sourceType: 'circle', | ||||||
|     className: 'public' |     className: 'public' | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     source_name: '矩形', |     sourceName: '矩形', | ||||||
|     key: 'DrawRect', |     key: 'DrawRect', | ||||||
|     source_type: 'rectangle', |     sourceType: 'rectangle', | ||||||
|     className: 'public' |     className: 'public' | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     source_name: '集结地', |     sourceName: '集结地', | ||||||
|     key: 'DrawAssemble', |     key: 'DrawAssemble', | ||||||
|     source_type: 'rendezvous', |     sourceType: 'rendezvous', | ||||||
|     className: 'public' |     className: 'public' | ||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     source_name: '箭头', |     sourceName: '箭头', | ||||||
|     key: 'DrawAttackArrow', |     key: 'DrawAttackArrow', | ||||||
|     source_type: 'attackArrow', |     sourceType: 'attackArrow', | ||||||
|     className: 'public' |     className: 'public' | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   { |   { | ||||||
|     source_name: '钳形箭头', |     sourceName: '钳形箭头', | ||||||
|     key: 'DrawPincerArrow', |     key: 'DrawPincerArrow', | ||||||
|     source_type: 'pincerArrow', |     sourceType: 'pincerArrow', | ||||||
|     className: 'public' |     className: 'public' | ||||||
|   } |   } | ||||||
|   // { |   // { | ||||||
|   //   source_name: "锁定", |   //   sourceName: "锁定", | ||||||
|   //   key: "lock", |   //   key: "lock", | ||||||
|   //   source_type: "unLock", |   //   sourceType: "unLock", | ||||||
|   //   className: "public", |   //   className: "public", | ||||||
|   // }, |   // }, | ||||||
| ]) | ]) | ||||||
| @ -161,34 +260,7 @@ const fold = () => { | |||||||
|   ) |   ) | ||||||
| } | } | ||||||
| const addMarker = (item: any) => { | const addMarker = (item: any) => { | ||||||
|   switch (item.source_type) { |   item.fun() | ||||||
|     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; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | |||||||
| @ -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> |     <template #footer> | ||||||
|       <button>确定</button> |       <button>确定</button> | ||||||
|     </template> |     </template> | ||||||
|  |  | ||||||
|   </Dialog> |   </Dialog> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| export const useRightMenu = () => { | export const useRightMenu = () => { | ||||||
|   const itemClick = (menuItem: any) => { |   const itemClick = (menuItem: any, eventBus) => { | ||||||
|     return menuItem.callback() |     return menuItem.callback(eventBus) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return { itemClick } |   return { itemClick } | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ import { ElMessage, ElMessageBox } from 'element-plus' | |||||||
| import { useTreeNode } from '@/views/components/tree/hooks/treeNode' | import { useTreeNode } from '@/views/components/tree/hooks/treeNode' | ||||||
|  |  | ||||||
| export const useRightOperate = () => { | export const useRightOperate = () => { | ||||||
|   const { getSelectedNodes, cusRemoveNode } = useTreeNode() |   const { getSelectedNodes, cusRemoveNode, cusUpdateNode } = useTreeNode() | ||||||
|  |  | ||||||
|   //添加文件 |   //添加文件 | ||||||
|   const addDirectory = () => { |   const addDirectory = () => { | ||||||
| @ -25,7 +25,14 @@ export const useRightOperate = () => { | |||||||
|   //导入模型 |   //导入模型 | ||||||
|   const addTrajectory = () => {} |   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) => { |   const deleteNode = (hasConfirm = true) => { | ||||||
|     ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', { |     ElMessageBox.confirm('此操作将永久删除节点及所有子节点, 是否继续?', '提示', { | ||||||
| @ -35,7 +42,7 @@ export const useRightOperate = () => { | |||||||
|     }) |     }) | ||||||
|       .then(async () => { |       .then(async () => { | ||||||
|         let selectNodes = getSelectedNodes(window.treeObj) |         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 }) |         const res = await TreeApi.removeDirectory({ ids }) | ||||||
|         if (res.code == 0) { |         if (res.code == 0) { | ||||||
|           ElMessage({ |           ElMessage({ | ||||||
| @ -62,9 +69,48 @@ export const useRightOperate = () => { | |||||||
|   const pressModel = () => {} |   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 = () => {} |   const layerRaise = () => {} | ||||||
|   //降低图层 |   //降低图层 | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
|         <div |         <div | ||||||
|           v-for="item in menus" |           v-for="item in menus" | ||||||
|           class="itemBox" |           class="itemBox" | ||||||
|           @click="itemClick(item)" |           @click="itemClick(item, eventBus)" | ||||||
|           @mouseup="$changeComponentShow('#rMenu', false)" |           @mouseup="$changeComponentShow('#rMenu', false)" | ||||||
|         > |         > | ||||||
|           <div class="itemIcon"> |           <div class="itemIcon"> | ||||||
| @ -32,6 +32,8 @@ import { useRightOperate } from './hooks/rightOperate' | |||||||
| import { useRightMenu } from './hooks/rightMenu' | import { useRightMenu } from './hooks/rightMenu' | ||||||
|  |  | ||||||
| import { getIP } from '@/utils' | import { getIP } from '@/utils' | ||||||
|  |  | ||||||
|  | const eventBus = inject("bus"); | ||||||
| const { rightMenus } = useRightOperate() | const { rightMenus } = useRightOperate() | ||||||
| const { itemClick } = useRightMenu() | const { itemClick } = useRightMenu() | ||||||
|  |  | ||||||
| @ -40,6 +42,7 @@ const rightClickTreeNode: any = ref() | |||||||
| // 初始化菜单 | // 初始化菜单 | ||||||
| const initMenus = (arr: any, treeNode: any) => { | const initMenus = (arr: any, treeNode: any) => { | ||||||
|   let rightMenu: any = [] |   let rightMenu: any = [] | ||||||
|  |   console.log('rightMenu2222', rightMenu) | ||||||
|   if (treeNode) { |   if (treeNode) { | ||||||
|     rightClickTreeNode.value = treeNode |     rightClickTreeNode.value = treeNode | ||||||
|     arr.forEach((menuId: any) => { |     arr.forEach((menuId: any) => { | ||||||
| @ -52,6 +55,7 @@ const initMenus = (arr: any, treeNode: any) => { | |||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|   } else rightMenu = [rightMenus.addDirectory] |   } else rightMenu = [rightMenus.addDirectory] | ||||||
|  |   console.log('rightMenu', rightMenu) | ||||||
|   menus.value = rightMenu |   menus.value = rightMenu | ||||||
| } | } | ||||||
| // 暴露方法给父组件 | // 暴露方法给父组件 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| import { $changeComponentShow } from '@/utils/communication' | import { $changeComponentShow } from '@/utils/communication' | ||||||
| import { useTreeNode } from './treeNode' | import { useTreeNode } from './treeNode' | ||||||
| import { TreeApi } from '@/api/tree' | import { TreeApi } from '@/api/tree' | ||||||
|  | import { initMapData } from '../initMapData' | ||||||
|  |  | ||||||
| export const useTree = () => { | export const useTree = () => { | ||||||
|   const rightMenuRef: any = ref() //右键菜单的实例 |   const rightMenuRef: any = ref() //右键菜单的实例 | ||||||
| @ -24,10 +25,10 @@ export const useTree = () => { | |||||||
|       if (isCtrl) { |       if (isCtrl) { | ||||||
|         let isSelected = window.treeObj |         let isSelected = window.treeObj | ||||||
|           .getSelectedNodes() |           .getSelectedNodes() | ||||||
|           .some((node: any) => node.source_id === treeNode.source_id) |           .some((node: any) => node.id === treeNode.id) | ||||||
|         if (isSelected) { |         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 { |         } else { | ||||||
|           // 如果节点未选中,则添加到选中列表 |           // 如果节点未选中,则添加到选中列表 | ||||||
|           nodes.value.push(treeNode) |           nodes.value.push(treeNode) | ||||||
| @ -48,11 +49,12 @@ export const useTree = () => { | |||||||
|     let selectNodes = getSelectedNodes(treeObj.value) |     let selectNodes = getSelectedNodes(treeObj.value) | ||||||
|     let isnewSelect = true //是否为新选中 |     let isnewSelect = true //是否为新选中 | ||||||
|     selectNodes.forEach((item: any) => { |     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)) |     if (!event.ctrlKey && (selectNodes.length < 2 || isnewSelect)) | ||||||
|       cusSelectNode(treeObj.value, treeNode) |       cusSelectNode(treeObj.value, treeNode) | ||||||
|     const menus = showRightMenu(event, treeObj.value) |     const menus = showRightMenu(event, treeObj.value) | ||||||
|  |     console.log('menus', menus) | ||||||
|     if (menus.length == 0) { |     if (menus.length == 0) { | ||||||
|       return |       return | ||||||
|     } |     } | ||||||
| @ -60,6 +62,16 @@ export const useTree = () => { | |||||||
|       rightMenuRef.value.initMenus(menus, treeNode) |       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 事件对象 |    * @param event 事件对象 | ||||||
| @ -87,9 +99,9 @@ export const useTree = () => { | |||||||
|     }) |     }) | ||||||
|     const list = newNode.map((item: any) => { |     const list = newNode.map((item: any) => { | ||||||
|       return { |       return { | ||||||
|         source_id: item.source_id, |         id: item.id, | ||||||
|         tree_index: item.tree_index, |         tree_index: item.tree_index, | ||||||
|         p_id: item.p_id |         parentId: item.parentId | ||||||
|       } |       } | ||||||
|     }) |     }) | ||||||
|     const res = await TreeApi.updateTree({ list }) |     const res = await TreeApi.updateTree({ list }) | ||||||
| @ -109,11 +121,11 @@ export const useTree = () => { | |||||||
|     // let nodes = this.treeObj.getSelectedNodes(); |     // let nodes = this.treeObj.getSelectedNodes(); | ||||||
|     // let source_ids = []; |     // let source_ids = []; | ||||||
|     // nodes.forEach((item) => { |     // 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) => { |     //   nodes.forEach((item) => { | ||||||
|     //     item.p_id = p_id; |     //     item.parentId = parentId; | ||||||
|     //     this.treeObj.updateNode(item); |     //     this.treeObj.updateNode(item); | ||||||
|     //   }); |     //   }); | ||||||
|     // }; |     // }; | ||||||
| @ -123,10 +135,10 @@ export const useTree = () => { | |||||||
|     //   updatePid( |     //   updatePid( | ||||||
|     //     { |     //     { | ||||||
|     //       source_ids, |     //       source_ids, | ||||||
|     //       p_id: "", |     //       parentId: "", | ||||||
|     //       trees: [ |     //       trees: [ | ||||||
|     //         { |     //         { | ||||||
|     //           source_id: treeNodes[0].source_id, |     //           id: treeNodes[0].id, | ||||||
|     //           tree_index: treeNodes[0].getIndex(), |     //           tree_index: treeNodes[0].getIndex(), | ||||||
|     //         }, |     //         }, | ||||||
|     //       ], |     //       ], | ||||||
| @ -146,18 +158,18 @@ export const useTree = () => { | |||||||
|     //   let trees = []; |     //   let trees = []; | ||||||
|     //   Nodes.forEach((item) => { |     //   Nodes.forEach((item) => { | ||||||
|     //     trees.push({ |     //     trees.push({ | ||||||
|     //       source_id: item.source_id, |     //       id: item.id, | ||||||
|     //       tree_index: item.getIndex(), |     //       tree_index: item.getIndex(), | ||||||
|     //     }); |     //     }); | ||||||
|     //   }); |     //   }); | ||||||
|     //   let p_id = ["prev", "next"].includes(moveType) |     //   let parentId = ["prev", "next"].includes(moveType) | ||||||
|     //     ? targetNode.p_id |     //     ? targetNode.parentId | ||||||
|     //     : targetNode.source_id; |     //     : targetNode.id; | ||||||
|     //   if (p_id == "") { |     //   if (parentId == "") { | ||||||
|     //     p_id = -1; |     //     parentId = -1; | ||||||
|     //   } |     //   } | ||||||
|     //   console.log("p_id", this.treeObj.getSelectedNodes()); |     //   console.log("parentId", this.treeObj.getSelectedNodes()); | ||||||
|     //   updatePid({ source_ids, p_id, trees }, (res) => { |     //   updatePid({ source_ids, parentId, trees }, (res) => { | ||||||
|     //     console.log(res); |     //     console.log(res); | ||||||
|     //   }); |     //   }); | ||||||
|     // } |     // } | ||||||
| @ -182,16 +194,16 @@ export const useTree = () => { | |||||||
|  |  | ||||||
|     // if ( |     // if ( | ||||||
|     //   ['prev', 'next', 'inner'].includes(moveType) && |     //   ['prev', 'next', 'inner'].includes(moveType) && | ||||||
|     //   ['pressModel', 'terrainDig'].includes(treeNodes[0].source_type) |     //   ['pressModel', 'terrainDig'].includes(treeNodes[0].sourceType) | ||||||
|     // ) { |     // ) { | ||||||
|     //   return false |     //   return false | ||||||
|     // } |     // } | ||||||
|     // if (['prev', 'next'].includes(moveType)) { |     // if (['prev', 'next'].includes(moveType)) { | ||||||
|     //   let parent = this.treeObj.getNodeByParam('source_id', targetNode.p_id, null) |     //   let parent = this.treeObj.getNodeByParam('id', targetNode.parentId, null) | ||||||
|     //   if (parent && !treeNodeOption.nodeType[parent.source_type].allowChildren) return false |     //   if (parent && !treeNodeOption.nodeType[parent.sourceType].allowChildren) return false | ||||||
|     // } |     // } | ||||||
|     // if (targetNode) { |     // if (targetNode) { | ||||||
|     //   if (moveType == 'inner' && !treeNodeOption.nodeType[targetNode.source_type].allowChildren) { |     //   if (moveType == 'inner' && !treeNodeOption.nodeType[targetNode.sourceType].allowChildren) { | ||||||
|     //     return false |     //     return false | ||||||
|     //   } |     //   } | ||||||
|     // } |     // } | ||||||
| @ -203,56 +215,51 @@ export const useTree = () => { | |||||||
|    * @param treeNode |    * @param treeNode | ||||||
|    */ |    */ | ||||||
|   const onCheck = async (event: any, treeId: any, treeNode: any) => { |   const onCheck = async (event: any, treeId: any, treeNode: any) => { | ||||||
|     const res = await TreeApi.updateTreeShow({ |     let params = JSON.parse(treeNode.params) | ||||||
|       ids: [treeNode.source_id], |     let entityObject = window.earth.entityMap.get(params.id) | ||||||
|       show: treeNode.is_show |     entityObject.show = treeNode.isShow | ||||||
|     }) |     params.show = treeNode.isShow | ||||||
|     if (res.code == 0) { |     let params2 = { | ||||||
|       ElMessage({ |       "id": treeNode.id, | ||||||
|         message: '操作成功', |       "params": params, | ||||||
|         type: 'success' |       "isShow": treeNode.isShow ? 1 : 0, | ||||||
|       }) |  | ||||||
|     } else { |  | ||||||
|       ElMessage({ |  | ||||||
|         message: '操作失败', |  | ||||||
|         type: 'error' |  | ||||||
|       }) |  | ||||||
|     } |     } | ||||||
|  |     TreeApi.updateDirectoryInfo(params2) | ||||||
|  |  | ||||||
|     //   let source_ids = []; |     //   let source_ids = []; | ||||||
|     //   nodes.forEach((item) => { |     //   nodes.forEach((item) => { | ||||||
|     //     if (item.isHidden == false) { |     //     if (item.isHidden == false) { | ||||||
|     //       source_ids.push(item.source_id); |     //       source_ids.push(item.id); | ||||||
|     //     } |     //     } | ||||||
|     //   }); |     //   }); | ||||||
|     //   //根据source_id获取对应的资源更改其在地球上的显示状态 |     //   //根据source_id获取对应的资源更改其在地球上的显示状态 | ||||||
|     //   let sourceStatus = (source_ids, status) => { |     //   let sourceStatus = (source_ids, status) => { | ||||||
|     //     source_ids.forEach((id) => { |     //     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); |     //       // console.log("ddddddddddddddddddddddd", id, node1); | ||||||
|     //       // let source1 = window._entityMap.get(id); |     //       // let source1 = window._entityMap.get(id); | ||||||
|     //       // console.log("source1", source1); |     //       // console.log("source1", source1); | ||||||
|     //       // return; |     //       // return; | ||||||
|     //       let source = window._entityMap.get(id); |     //       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); |     //       console.log("source", source, node); | ||||||
|     //       node.source_name = node.oldname || node.source_name; |     //       node.sourceName = node.oldname || node.sourceName; | ||||||
|     //       if (node.source_type == "Feature") { |     //       if (node.sourceType == "Feature") { | ||||||
|     //         let shp = window._entityMap.get(node.fid); |     //         let shp = window._entityMap.get(node.fid); | ||||||
|     //         shp.setShow(status, id); |     //         shp.setShow(status, id); | ||||||
|     //         return; |     //         return; | ||||||
|     //       } |     //       } | ||||||
|     //       if (node.source_type == "FeatureCollection") { |     //       if (node.sourceType == "FeatureCollection") { | ||||||
|     //         let shp = window._entityMap.get(node.fid); |     //         let shp = window._entityMap.get(node.fid); | ||||||
|     //         console.log("shp", shp); |     //         console.log("shp", shp); | ||||||
|     //         node.children.forEach((item) => { |     //         node.children.forEach((item) => { | ||||||
|     //           shp.setShow(status, item.source_id); |     //           shp.setShow(status, item.id); | ||||||
|     //           console.log("item", status, item); |     //           console.log("item", status, item); | ||||||
|     //         }); |     //         }); | ||||||
|     //         return; |     //         return; | ||||||
|     //       } |     //       } | ||||||
|     //       if (["kml", "gdb", "shp"].includes(node.source_type)) { |     //       if (["kml", "gdb", "shp"].includes(node.sourceType)) { | ||||||
|     //         let entity = window._entityMap.get(node.source_id); |     //         let entity = window._entityMap.get(node.id); | ||||||
|     //         if (entity) { |     //         if (entity) { | ||||||
|     //           entity.show = status; |     //           entity.show = status; | ||||||
|     //           if (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); |     //         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; |     //         let num; | ||||||
|     //         if (status) { |     //         if (status) { | ||||||
|     //           num = Infinity; |     //           num = Infinity; | ||||||
| @ -274,9 +281,9 @@ export const useTree = () => { | |||||||
|     //         node.detail.repeat = num; |     //         node.detail.repeat = num; | ||||||
|     //         YJ.Global.FlyRoam.setRepeat(num); |     //         YJ.Global.FlyRoam.setRepeat(num); | ||||||
|     //       } |     //       } | ||||||
|     //       if (window.right_entityMap.get(treeNode.source_id)) |     //       if (window.right_entityMap.get(treeNode.id)) | ||||||
|     //         window.right_entityMap.get(treeNode.source_id).show = status; |     //         window.right_entityMap.get(treeNode.id).show = status; | ||||||
|     //       if (node.source_type == "path") { |     //       if (node.sourceType == "path") { | ||||||
|     //         let pathModel = window._entityMap.get(id); |     //         let pathModel = window._entityMap.get(id); | ||||||
|     //         // console.log("pathModel+++++++++++++", pathModel, pathModel.modelShow); |     //         // console.log("pathModel+++++++++++++", pathModel, pathModel.modelShow); | ||||||
|     //         if (pathModel) { |     //         if (pathModel) { | ||||||
| @ -293,15 +300,15 @@ export const useTree = () => { | |||||||
|     //     }); |     //     }); | ||||||
|     //   }; |     //   }; | ||||||
|     //   //调用接口更改数据库is_show的值 |     //   //调用接口更改数据库is_show的值 | ||||||
|     //   if (treeNode.is_show) { |     //   if (treeNode.isShow) { | ||||||
|     //     showSource({ source_ids }, (data) => { |     //     showSource({ source_ids }, (data) => { | ||||||
|     //       console.log(data); |     //       console.log(data); | ||||||
|     //       sourceStatus(source_ids, treeNode.is_show); |     //       sourceStatus(source_ids, treeNode.isShow); | ||||||
|     //     }); |     //     }); | ||||||
|     //   } else { |     //   } else { | ||||||
|     //     hideSource({ source_ids }, (data) => { |     //     hideSource({ source_ids }, (data) => { | ||||||
|     //       console.log(data); |     //       console.log(data); | ||||||
|     //       sourceStatus(source_ids, treeNode.is_show); |     //       sourceStatus(source_ids, treeNode.isShow); | ||||||
|     //     }); |     //     }); | ||||||
|     //   } |     //   } | ||||||
|     //   // YJ.Global.splitScreen.setActiveId([]); |     //   // YJ.Global.splitScreen.setActiveId([]); | ||||||
| @ -366,23 +373,24 @@ export const useTree = () => { | |||||||
|       onClick: onClick, |       onClick: onClick, | ||||||
|       onDrop: onDrop, |       onDrop: onDrop, | ||||||
|       beforeDrop: beforeDrop, |       beforeDrop: beforeDrop, | ||||||
|       onCheck: onCheck |       onCheck: onCheck, | ||||||
|  |       onDblClick: onDblClick | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // 树的数据 |   // 树的数据 | ||||||
|   const zNodes = ref([ |   const zNodes = ref([ | ||||||
|     { |     { | ||||||
|       source_id: 1, |       id: 1, | ||||||
|       p_id: 0, |       parentId: 0, | ||||||
|       source_name: '111', |       sourceName: '111', | ||||||
|       is_show: true |       isShow: true | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       source_id: 2, |       id: 2, | ||||||
|       p_id: 0, |       parentId: 0, | ||||||
|       source_name: '222', |       sourceName: '222', | ||||||
|       is_show: true |       isShow: true | ||||||
|     } |     } | ||||||
|   ]) |   ]) | ||||||
|  |  | ||||||
| @ -408,12 +416,26 @@ export const useTree = () => { | |||||||
|       treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value) |       treeObj.value = $.fn.zTree.init($(selector), setting, zNodes.value) | ||||||
|       window.treeObj = treeObj.value |       window.treeObj = treeObj.value | ||||||
|       window.AllNodes = treeObj.value.getNodes() |       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 { |   return { | ||||||
|     initTree, |     initTree, | ||||||
|     setting, |     setting, | ||||||
|     rightMenuRef |     rightMenuRef, | ||||||
|  |     initTreeCallBack | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -71,6 +71,12 @@ export const useTreeNode = () => { | |||||||
|       // detailFun: get_detail_groundImage, |       // detailFun: get_detail_groundImage, | ||||||
|       // allowChildren: false, |       // allowChildren: false, | ||||||
|     }, |     }, | ||||||
|  |     groundSvg: { | ||||||
|  |       rightMenus: ['edit', 'del', 'setView', 'resetView'] | ||||||
|  |       // render: renderGroundImage, | ||||||
|  |       // detailFun: get_detail_groundImage, | ||||||
|  |       // allowChildren: false, | ||||||
|  |     }, | ||||||
|     waterl: { |     waterl: { | ||||||
|       rightMenus: ['edit', 'del', 'setView', 'resetView'] |       rightMenus: ['edit', 'del', 'setView', 'resetView'] | ||||||
|       // render: renderSpout, |       // render: renderSpout, | ||||||
| @ -429,16 +435,16 @@ export const useTreeNode = () => { | |||||||
|    */ |    */ | ||||||
|   const cusAddNodes = (treeObj: any, parentNodeId: any, newNodes: any, isSilent?: any) => { |   const cusAddNodes = (treeObj: any, parentNodeId: any, newNodes: any, isSilent?: any) => { | ||||||
|     // newNodes.forEach((node: 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.detail && typeof node.detail == 'string') node.detail = JSON.parse(node.detail) | ||||||
|     //   // if(node.p_id) |     //   // if(node.parentId) | ||||||
|     //   YJ.Global.splitScreen.setActiveId([node.source_id]) |     //   YJ.Global.splitScreen.setActiveId([node.id]) | ||||||
|     // }) |     // }) | ||||||
|     let parentNode = null |     let parentNode = null | ||||||
|     if (Object.prototype.toString.call(parentNodeId) === '[object Object]') |     if (Object.prototype.toString.call(parentNodeId) === '[object Object]') | ||||||
|       parentNode = parentNodeId |       parentNode = parentNodeId | ||||||
|     else { |     else { | ||||||
|       parentNode = treeObj.getNodeByParam('source_id', parentNodeId, null) |       parentNode = treeObj.getNodeByParam('id', parentNodeId, null) | ||||||
|     } |     } | ||||||
|     let arr = treeObj.addNodes(parentNode, newNodes, isSilent) |     let arr = treeObj.addNodes(parentNode, newNodes, isSilent) | ||||||
|     treeObj.selectNode(arr[arr.length - 1]) |     treeObj.selectNode(arr[arr.length - 1]) | ||||||
| @ -459,7 +465,7 @@ export const useTreeNode = () => { | |||||||
|       allNodes = allNodes.concat(treeObj.transformToArray(node)) |       allNodes = allNodes.concat(treeObj.transformToArray(node)) | ||||||
|     }) |     }) | ||||||
|     allNodes.forEach((node: any) => { |     allNodes.forEach((node: any) => { | ||||||
|       _idSet.add(node.source_id) |       _idSet.add(node.id) | ||||||
|       treeObj.removeNode(node) |       treeObj.removeNode(node) | ||||||
|     }) |     }) | ||||||
|     // treeObj.getNodes() |     // treeObj.getNodes() | ||||||
| @ -486,6 +492,18 @@ export const useTreeNode = () => { | |||||||
|     return siblings |     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'] |       if (selectedNodes.length == 0) arr = ['addDirectory'] | ||||||
|       else { |       else { | ||||||
|         try { |         try { | ||||||
|           arr = nodeType[selectedNodes[0].source_type].rightMenus |           arr = nodeType[selectedNodes[0].sourceType].rightMenus | ||||||
|         } catch (e) { |         } catch (e) { | ||||||
|           arr = [] |           arr = [] | ||||||
|         } |         } | ||||||
| @ -594,6 +612,7 @@ export const useTreeNode = () => { | |||||||
|     cusAddNodes, |     cusAddNodes, | ||||||
|     getSameLevel, |     getSameLevel, | ||||||
|     cusRemoveNode, |     cusRemoveNode, | ||||||
|  |     cusUpdateNode, | ||||||
|     findParentId, |     findParentId, | ||||||
|     findTreeIndex |     findTreeIndex | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -82,7 +82,7 @@ import rightMenu from './components/rightMenu.vue' | |||||||
| import { $changeComponentShow } from '@/utils/communication' | import { $changeComponentShow } from '@/utils/communication' | ||||||
| import { bus } from '@/utils/bus' | import { bus } from '@/utils/bus' | ||||||
|  |  | ||||||
| const { initTree, rightMenuRef } = useTree() | const { initTree, rightMenuRef, initTreeCallBack } = useTree() | ||||||
|  |  | ||||||
| const { t } = useI18n() | const { t } = useI18n() | ||||||
| const isShow = ref(false) | const isShow = ref(false) | ||||||
| @ -164,6 +164,9 @@ onMounted(() => { | |||||||
|   //   initTree() |   //   initTree() | ||||||
|   // }) |   // }) | ||||||
| }) | }) | ||||||
|  | defineExpose({ | ||||||
|  |   initTreeCallBack | ||||||
|  | }) | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style lang="scss"> | <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> |   <Headers></Headers> | ||||||
|   <div id="earthContainer" class="fullSize"></div> |   <div id="earthContainer" class="fullSize"></div> | ||||||
|   <Tree class="tree" ref="tree"></Tree> |   <Tree class="tree" ref="tree"></Tree> | ||||||
|  |   <component :is="currentComponent" ref="dynamicComponentRef" /> | ||||||
|  |   <richText></richText> | ||||||
|   <addDirectory ref="adddirectoryBox" class="adddirectoryBox absolute zIndex999"></addDirectory> |   <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> |   <Visibility ref="visibility"></Visibility> | ||||||
|   <CircleViewShed ref="CircleViewShed"></CircleViewShed> |   <CircleViewShed ref="CircleViewShed"></CircleViewShed> | ||||||
| @ -22,12 +23,22 @@ | |||||||
|   <CoorLocation ref="CoorLocation"></CoorLocation> |   <CoorLocation ref="CoorLocation"></CoorLocation> | ||||||
|   <ScreenShot ref="ScreenShot"></ScreenShot> |   <ScreenShot ref="ScreenShot"></ScreenShot> | ||||||
|   <TerrainExcavation ref="TerrainExcavation"></TerrainExcavation> |   <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> | </template> | ||||||
|  |  | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
|  | import { inject, shallowRef, ref } from "vue"; | ||||||
| import Headers from '../components/headers/index.vue' | import Headers from '../components/headers/index.vue' | ||||||
| import Tree from '../components/tree/index.vue' | import Tree from '../components/tree/index.vue' | ||||||
| import 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 addDirectory from '@/components/dialog/directory.vue' | ||||||
| import firstMenu from '@/views/components/leftSide/leftSideFirst.vue' | import firstMenu from '@/views/components/leftSide/leftSideFirst.vue' | ||||||
| import bottomMenu from '@/views/components/bottomSide/bottomSide.vue' | import bottomMenu from '@/views/components/bottomSide/bottomSide.vue' | ||||||
| @ -44,9 +55,70 @@ import FlyRoam from '../components/propertyBox/FlyRoam.vue' | |||||||
| import CoorLocation from '../components/propertyBox/CoorLocation.vue' | import CoorLocation from '../components/propertyBox/CoorLocation.vue' | ||||||
| import ScreenShot from '../components/propertyBox/ScreenShot.vue' | import ScreenShot from '../components/propertyBox/ScreenShot.vue' | ||||||
| import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue' | import TerrainExcavation from '../components/propertyBox/TerrainExcavation.vue' | ||||||
|  | import { GisApi } from '@/api/gisApi' | ||||||
|  |  | ||||||
| const createEarth = () => { | const firstMenuRef = ref(null) | ||||||
|   window.earth = new YJ.YJEarth('earthContainer') | 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, { |   // YJ.Global.setDefaultView(window.earth, { | ||||||
|   //   destination: { lng: 100, lat: 30, alt: 10 }, |   //   destination: { lng: 100, lat: 30, alt: 10 }, | ||||||
|   //   orientation: { |   //   orientation: { | ||||||
| @ -58,6 +130,34 @@ const createEarth = () => { | |||||||
|   // new YJ.Tools(window.earth).flyHome(0) |   // 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 () => { | onMounted(async () => { | ||||||
|   await YJ.on() |   await YJ.on() | ||||||
|   createEarth() |   createEarth() | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user