Fuyuu
12 months ago
7 changed files with 3359 additions and 1351 deletions
File diff suppressed because it is too large
@ -0,0 +1,521 @@ |
|||
<template> |
|||
<div class="create-model-modal" v-if="winVisible"> |
|||
<Window |
|||
:title="title" |
|||
@cancel="cancel" |
|||
@ok="ok" |
|||
:width="width" |
|||
:minWidth="600" |
|||
:height="height" |
|||
:left="left" |
|||
:top="top" |
|||
:floatright="false" |
|||
:footervisible="true" |
|||
v-show="!creating" |
|||
:expand="expand" |
|||
> |
|||
<div class="object-box"> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">监控点名称:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="name" class="name-input" style="height: 90%; width: 100%" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">所属区域:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjSelect id="area-select" title="name" :list="areaList" v-model:value="selectArea" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">像素大小:</label> |
|||
<div class="custom-item-box"> |
|||
<a-slider v-model:value="minimumPixelSize" :min="0" :max="256" :step="1" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">经纬度:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="LngLatHeight[0]" type="number" class="xyz-input" /> |
|||
<input v-model="LngLatHeight[1]" type="number" class="xyz-input y-margin" /> |
|||
<input v-model="LngLatHeight[2]" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">旋转:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="rotation[0]" class="xyz-input" type="number" /> |
|||
<input v-model="rotation[1]" class="xyz-input y-margin" type="number" /> |
|||
<input v-model="rotation[2]" class="xyz-input" type="number" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">缩放:</label> |
|||
<div class="custom-item-box"> |
|||
<xbsjScale v-model:scale="scale" style="height: 90%; width: 100%"></xbsjScale> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex; align-items: center; justify-content: center" class="custom-item"> |
|||
<button |
|||
@click="modelState('creating')" |
|||
:class="['xbsj-button', 'edit-model-btn', creating ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%" |
|||
> |
|||
拾取 |
|||
</button> |
|||
<button |
|||
@click="currentModel.positionEditing = true" |
|||
:class="['xbsj-button', 'edit-model-btn', !currentModel || positionEditing ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%" |
|||
> |
|||
移动 |
|||
</button> |
|||
<button |
|||
@click="modelState('rotationEditing')" |
|||
:class="['xbsj-button', 'edit-model-btn', !currentModel || rotationEditing ? 'edit-model-btn-disable' : '']" |
|||
:disabled="rotationEditing" |
|||
style="width: 20%" |
|||
> |
|||
旋转 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
<div class="Mask"></div> |
|||
</Window> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { onMounted, nextTick, defineComponent, ref, getCurrentInstance, computed } from 'vue'; |
|||
import xbsjScale from '/@/components/earthMap/components/xbsjScale.vue'; |
|||
import XbsjSelect from '/@/components/earthMap/components/XbsjSelect.vue'; |
|||
import XbsjColorButton from '/@/components/earthMap/components/XbsjColorButton.vue'; |
|||
import upload from '/@/components/earthMap/components/upload.vue'; |
|||
import Window from '@/components/earthMap/components/Window.vue'; |
|||
import { defHttp } from '/@/utils/http/axios'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
import $ from 'jquery'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'AddMonitorPointCom', |
|||
components: { |
|||
xbsjScale, |
|||
XbsjSelect, |
|||
upload, |
|||
XbsjColorButton, |
|||
Window, |
|||
}, |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '添加监控点', |
|||
}, |
|||
}, |
|||
setup() { |
|||
const { proxy }: any = getCurrentInstance(); |
|||
const { createMessage } = useMessage(); |
|||
// 宽高 |
|||
let widthCoefficient = ref(0.3); |
|||
let heightCoefficient = ref(0.5); |
|||
// 计算弹窗宽高定位 |
|||
const width = computed(() => { |
|||
return window.outerWidth * widthCoefficient.value; |
|||
}); |
|||
const height = computed(() => { |
|||
return window.outerHeight * heightCoefficient.value; |
|||
}); |
|||
const top = computed(() => { |
|||
return window.outerHeight * ((1.0 - heightCoefficient.value - 0.15) / 2); |
|||
}); |
|||
const left = computed(() => { |
|||
return (window.outerWidth * (1.0 - widthCoefficient.value)) / 2; |
|||
}); |
|||
// 窗口显示或隐藏 |
|||
let winVisible = ref(true); |
|||
// 当前模型 |
|||
let currentModel: any = ref(null); |
|||
// 是否更新模型 |
|||
let isUpdateModel = ref(false); |
|||
// 取消还原数据 |
|||
let revert = ref(null); |
|||
// 监控点名称 |
|||
let name = ref(''); |
|||
// 所属区域列表 |
|||
let areaList = ref([]); |
|||
// 选中所属区域 |
|||
let selectArea: any = ref(null); |
|||
// 像素大小 |
|||
let minimumPixelSize = ref(80); |
|||
// 俯仰角度 |
|||
let LngLatHeight = ref([0, 0, 0]); |
|||
// 旋转角度 |
|||
let rotation = ref([0, 0, 0]); |
|||
// 开启旋转辅助 |
|||
let rotationEditing = ref(false); |
|||
// 开启移动辅助 |
|||
let positionEditing = ref(false); |
|||
// 缩放 |
|||
let scale = ref([1, 1, 1]); |
|||
// 是否跟随鼠标状态 |
|||
let creating = ref(false); |
|||
// 是否展开表单项 |
|||
let expand = ref(true); |
|||
// 提交对象 |
|||
let submitObject: any = ref({}); |
|||
// 获取区域数据 |
|||
function getAreas() { |
|||
const submitData: any = { |
|||
pageNo: 1, |
|||
pageSize: 999, |
|||
}; |
|||
return defHttp |
|||
.get( |
|||
{ |
|||
url: '/military/msMapLine/list', |
|||
params: submitData, |
|||
}, |
|||
{ isTransformResponse: false } |
|||
) |
|||
.then((res) => { |
|||
if (res.success) { |
|||
areaList.value = res.result.records; |
|||
} |
|||
}); |
|||
} |
|||
// 取消 |
|||
function cancel() { |
|||
if (isUpdateModel.value) { |
|||
// 调用更新时的取消 |
|||
updateClose(); |
|||
} else { |
|||
// 调用创建时的取消 |
|||
close(); |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addMonitorPointComShow = false; |
|||
} |
|||
// 更新时的取消方法 |
|||
function updateClose() { |
|||
// 还原数据 |
|||
if (currentModel.value) { |
|||
currentModel.value.xbsjFromJSON(revert.value); |
|||
currentModel.value.editing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value.rotationEditing = false; |
|||
} |
|||
} |
|||
// 创建时的取消方法 |
|||
function close() { |
|||
// 模型不为空时,销毁模型 |
|||
if (currentModel.value) { |
|||
if (currentModel.value.addViewShedReturn) { |
|||
window.$earth.czm.viewer.entities.remove(currentModel.value.addViewShedReturn); |
|||
} |
|||
currentModel.value.editing = false; |
|||
currentModel.value.destroy(); |
|||
} |
|||
} |
|||
// 确认 |
|||
function ok() { |
|||
// 校验表单项 |
|||
if (name.value == null || name.value.length <= 0) { |
|||
createMessage.warning('请填写监控点名称', 2); |
|||
return; |
|||
} else if (selectArea.value == null || selectArea.value.id <= 0) { |
|||
// 非区域类型,区域效验 |
|||
createMessage.warning('请选择所属区域', 2); |
|||
return; |
|||
} |
|||
// 关闭编辑状态 |
|||
currentModel.value.editing = false; |
|||
// 提交数据 |
|||
submitData(); |
|||
} |
|||
// 提交数据方法 |
|||
function submitData() { |
|||
// 查找最后一个/所在位置 |
|||
let startNum = currentModel.value.url.lastIndexOf('/') + 1; |
|||
// 获取出模型名称 监控点 |
|||
let modelName = ''; |
|||
if (startNum > -1) { |
|||
modelName = currentModel.value.url.substring(startNum, currentModel.value.url.length); |
|||
} |
|||
submitObject.value = { |
|||
id: null, |
|||
createBy: null, |
|||
createTime: null, |
|||
updateBy: null, |
|||
updateTime: null, |
|||
sitecode: null, |
|||
sitename: name.value, // 名称 |
|||
longitude: LngLatHeight.value[0], // x坐标 |
|||
latitude: LngLatHeight.value[1], // y坐标 |
|||
height: LngLatHeight.value[2], // z坐标 |
|||
yaw: rotation.value[0], // x旋转 |
|||
pitch: rotation.value[1], // y旋转 |
|||
roll: rotation.value[2], // z旋转 |
|||
lineId: selectArea.value.id ? selectArea.value.id : null, // 区域id |
|||
state: 1, // 数据状态 |
|||
modelUrl: modelName, // 模型url地址 |
|||
scale: currentModel.value.scale ? currentModel.value.scale : 1, // 整体缩放比例 默认1 |
|||
xyzScale: scale.value.toString(), // xyz缩放比例 |
|||
minimumPixelSize: minimumPixelSize.value, // 最小像素大小 |
|||
}; |
|||
let request: any = null; |
|||
// 提交地址 |
|||
let url = ''; |
|||
|
|||
if (isUpdateModel.value) { |
|||
// 设置url为编辑地址,设置方法为put 设置记录id |
|||
url = '/military/camera/site/edit'; |
|||
submitObject.value.id = currentModel.value.customProp; |
|||
request = defHttp.put({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} else { |
|||
// 设置url为新增地址,设置方法为post |
|||
url = '/military/camera/site/add'; |
|||
request = defHttp.post({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} |
|||
// 提交数据,等待回复 |
|||
request |
|||
.then(function (response) { |
|||
// 数据回复,并成功 |
|||
if (response.success) { |
|||
// 设置显示节点的ref为 node_ref |
|||
const lineId = 'node_' + selectArea.value.id; |
|||
// 当前处于新增状态 |
|||
if (!isUpdateModel.value) { |
|||
// 设置父节点 |
|||
const parent = window.$earth.sceneTree.$refs[lineId].children[0]; |
|||
// 真实的叶子节点 |
|||
let node = new window.XE.SceneTree.Leaf(currentModel.value); |
|||
// 设置叶子节点的ref |
|||
node.ref = response.result; |
|||
// 将id存入customProp属性中 |
|||
currentModel.value.customProp = response.result; |
|||
// 设置树中显示文 |
|||
node.title = name.value; |
|||
// 设置节点的name,用来存储,区域id。name属性不在模型树上显示,故而只用作数据储存功能 |
|||
node.name = selectArea.value.id; |
|||
// 将此节点添加到树中 |
|||
window.$earth.sceneTree.root.children.push(node); |
|||
// 移除真实叶子节点显示的dom |
|||
nextTick(() => { |
|||
$('#earthContainer>div>div>div:nth-child(5)') |
|||
.children('div') |
|||
.eq(1) |
|||
.children() |
|||
.eq(0) |
|||
.children() |
|||
.eq(0) |
|||
.children() |
|||
.each((index, element) => { |
|||
if (index <= 1) { |
|||
return; |
|||
} |
|||
const paddingLeft = $(element).children().eq(0).css('padding-left'); |
|||
if (paddingLeft === '10px') { |
|||
$(element).css('display', 'none'); |
|||
} |
|||
}); |
|||
}); |
|||
// 虚假的节点 |
|||
const shamNode = { |
|||
ref: 'node_' + response.result, // 设置节点ref |
|||
title: name.value, // 设置节点显示文字 |
|||
expand: false, |
|||
children: [], |
|||
}; |
|||
// 树中加入并显示该节点 |
|||
parent.children.push(shamNode); |
|||
// 提示用户 |
|||
createMessage.success('添加成功!', 2); |
|||
} else { |
|||
//当前处于更新状态 |
|||
// 获取更新的虚假节点 |
|||
const shamNode = window.$earth.sceneTree.$refs['node_' + submitObject.value.id]; |
|||
// 更新虚假节点的显示文字 |
|||
shamNode.title = name.value; |
|||
// 设置name属性 |
|||
currentModel.value.name = name.value; |
|||
moveNode('Model'); |
|||
// 提示用户 |
|||
createMessage.success('修改成功!', 2); |
|||
} |
|||
} |
|||
}) |
|||
.then(function () { |
|||
finish(); |
|||
}); |
|||
} |
|||
// 提交完成 |
|||
function finish() { |
|||
if (currentModel.value) { |
|||
// 释放当前模型的引用 |
|||
currentModel.value.rotationEditing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value = null; |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addMonitorPointComShow = false; |
|||
} |
|||
// 修改属性状态,取反 |
|||
function modelState(propName) { |
|||
proxy[propName] = !proxy[propName]; |
|||
} |
|||
// 添加监控点模型(监控杆) |
|||
function addModel() { |
|||
// 创建模型 |
|||
const model = new window.XE.Obj.Model(window.$earth); |
|||
// 设置视距 |
|||
model.distanceDisplayCondition = [1, 30000]; |
|||
// 设置模型地址 |
|||
model.url = window._CONFIG['domianURL'] + '/sys/common/static/dxgG.gltf'; |
|||
// 设置缩放倍数 |
|||
model.scale = 0.03; |
|||
// 绑定属性 |
|||
bindModelProps(model); |
|||
// 设备像素 |
|||
minimumPixelSize.value = 80; |
|||
return model; |
|||
} |
|||
// 绑定模型属性 |
|||
function bindModelProps(model) { |
|||
// 绑定位移 |
|||
model.disposers.push(window.XE.MVVM.bindPosition(proxy, 'LngLatHeight', model, 'xbsjPosition')); |
|||
// 绑定角度 |
|||
model.disposers.push(window.XE.MVVM.bindRotation(proxy, 'rotation', model, 'xbsjRotation')); |
|||
// 绑定缩放 |
|||
model.disposers.push(window.XE.MVVM.bind(proxy, 'scale', model, 'xbsjScale')); |
|||
// 绑定编辑状态 |
|||
model.disposers.push(window.XE.MVVM.bind(proxy, 'creating', model, 'creating')); |
|||
// 绑定旋转状态 |
|||
model.disposers.push(window.XE.MVVM.bind(proxy, 'rotationEditing', model, 'rotationEditing')); |
|||
// 绑定最小像素 |
|||
model.disposers.push(window.XE.MVVM.bind(proxy, 'minimumPixelSize', model, 'minimumPixelSize')); |
|||
} |
|||
// 移动节点 |
|||
function moveNode(type) { |
|||
if (!isUpdateModel.value) { |
|||
return false; |
|||
} |
|||
const newNodel = 'node_' + selectArea.value.id; |
|||
const moveAreaNode = window.$earth.sceneTree.$refs[newNodel] || window.$earth.sceneTree.$refs['nodeSecondary_' + selectArea.value.id]; |
|||
if (moveAreaNode) { |
|||
let moveNode = null; |
|||
if (type == 'Model') { |
|||
moveNode = moveAreaNode.children[0]; |
|||
} else if (type == 'ld') { |
|||
moveNode = moveAreaNode; |
|||
} else { |
|||
moveNode = moveAreaNode.children[2]; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// 设置当前状态为添加 |
|||
isUpdateModel.value = false; |
|||
// 获取区域数据 |
|||
getAreas().then(() => { |
|||
// 折叠面板 |
|||
expand.value = true; |
|||
// 创建并绑定模型 |
|||
currentModel.value = addModel(); |
|||
}); |
|||
}); |
|||
|
|||
return { |
|||
widthCoefficient, |
|||
heightCoefficient, |
|||
width, |
|||
height, |
|||
top, |
|||
left, |
|||
winVisible, |
|||
currentModel, |
|||
name, |
|||
areaList, |
|||
selectArea, |
|||
minimumPixelSize, |
|||
LngLatHeight, |
|||
rotation, |
|||
rotationEditing, |
|||
positionEditing, |
|||
scale, |
|||
creating, |
|||
expand, |
|||
getAreas, |
|||
bindModelProps, |
|||
modelState, |
|||
cancel, |
|||
ok, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.object-box { |
|||
width: 100%; |
|||
height: 86%; |
|||
|
|||
label { |
|||
color: #ffffff; |
|||
} |
|||
} |
|||
:deep(.custom-item-box > div > input) { |
|||
width: 45% !important; |
|||
margin-right: 0% !important; |
|||
} |
|||
:deep(.custom-label) { |
|||
width: 15% !important; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
color: #ffffff; |
|||
} |
|||
:deep(.object-box .custom-item) { |
|||
height: 10%; |
|||
margin-top: 2%; |
|||
} |
|||
:deep(.custom-item-box) { |
|||
padding-left: 5% !important; |
|||
width: 80% !important; |
|||
} |
|||
.name-input { |
|||
height: 90%; |
|||
width: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
.xyz-input { |
|||
height: 90%; |
|||
width: 30%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
|
|||
.y-margin { |
|||
margin-left: 5%; |
|||
margin-right: 5%; |
|||
} |
|||
.edit-model-btn { |
|||
cursor: pointer; |
|||
line-height: 5%; |
|||
} |
|||
|
|||
.edit-model-btn-disable { |
|||
cursor: not-allowed; |
|||
} |
|||
</style> |
@ -0,0 +1,638 @@ |
|||
<!-- |
|||
* @Author: Fuyuu 1805498209@qq.com |
|||
* @Date: 2024-01-10 15:19:50 |
|||
* @LastEditors: Fuyuu 1805498209@qq.com |
|||
* @LastEditTime: 2024-01-11 15:50:45 |
|||
* @FilePath: \dt-admin-pc-v2\src\components\earthMap\toolbar\AddWaveCom.vue |
|||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE |
|||
--> |
|||
<template> |
|||
<div class="create-model-modal" v-if="winVisible"> |
|||
<Window |
|||
:title="title" |
|||
@cancel="cancel" |
|||
@ok="ok" |
|||
:width="width" |
|||
:minWidth="600" |
|||
:height="height" |
|||
:left="left" |
|||
:top="top" |
|||
:floatright="false" |
|||
:footervisible="true" |
|||
v-show="!creating" |
|||
:expand="expand" |
|||
> |
|||
<div class="object-box"> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">雷达名称:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="name" class="name-input" style="height: 90%; width: 100%" @change="nameChange(currentModel)" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">所属区域:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjSelect id="area-select" title="name" :list="areaList" v-model:value="selectArea" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">主机设备:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjSelect title="deviceName" :list="hostDeviceList" v-model:value="selectHostDevice" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">设备编码:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="selectDeviceNum" class="name-input" style="height: 90%; width: 100%" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex; height: 20%" class="custom-item"> |
|||
<label class="custom-label">上传图标:</label> |
|||
<div class="custom-item-box"> |
|||
<div class="upload-box"> |
|||
<upload v-model:file="uploadFile" :pre-view-url="previewImgUrl" :isUpdateModel="isUpdateModel" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">经纬度:</label> |
|||
<div class="custom-item-box"> |
|||
<!-- <XbsjLngLatHeight v-model="LngLatHeight" style="height: 90%; width: 100%"></XbsjLngLatHeight> --> |
|||
<input v-model="LngLatHeight[0]" type="number" class="xyz-input" /> |
|||
<input v-model="LngLatHeight[1]" type="number" class="xyz-input y-margin" /> |
|||
<input v-model="LngLatHeight[2]" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">扫描颜色:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjColorButton style="height: 30px" v-model:color="radarColor"> </XbsjColorButton> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">法线偏移角度:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="radarShifting" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">扫描范围:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="radarRange" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">扫描半径:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="radarRadius" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex; justify-content: center" class="custom-item"> |
|||
<button |
|||
@click="modelState('creating')" |
|||
:class="['xbsj-button', 'edit-model-btn', creating ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%; display: flex; align-items: center; justify-content: center" |
|||
> |
|||
拾取 |
|||
</button> |
|||
<button |
|||
@click="currentModel.editing = true" |
|||
:class="['xbsj-button', 'edit-model-btn', creating ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%; display: flex; align-items: center; justify-content: center" |
|||
> |
|||
移动 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</Window> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { onMounted, defineComponent, ref, getCurrentInstance, computed, watch } from 'vue'; |
|||
import xbsjScale from '/@/components/earthMap/components/xbsjScale.vue'; |
|||
import XbsjSelect from '/@/components/earthMap/components/XbsjSelect.vue'; |
|||
import XbsjColorButton from '/@/components/earthMap/components/XbsjColorButton.vue'; |
|||
import upload from '/@/components/earthMap/components/upload.vue'; |
|||
import Window from '@/components/earthMap/components/Window.vue'; |
|||
import { defHttp } from '/@/utils/http/axios'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
import { addViewShedRadar } from '@/utils/earthMap/earthObj'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'AddWaveCom', |
|||
components: { |
|||
xbsjScale, |
|||
XbsjSelect, |
|||
upload, |
|||
XbsjColorButton, |
|||
Window, |
|||
}, |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '添加雷达', |
|||
}, |
|||
setLabelStatus: { |
|||
type: Function, |
|||
default: null, |
|||
}, |
|||
setIconByRef: { |
|||
type: Function, |
|||
default: null, |
|||
}, |
|||
el: { |
|||
type: Object, |
|||
default: null, |
|||
}, |
|||
}, |
|||
setup(props) { |
|||
const { proxy }: any = getCurrentInstance(); |
|||
const { createMessage } = useMessage(); |
|||
// 宽高 |
|||
let widthCoefficient = ref(0.3); |
|||
let heightCoefficient = ref(0.5); |
|||
// 计算弹窗宽高定位 |
|||
const width = computed(() => { |
|||
return window.outerWidth * widthCoefficient.value; |
|||
}); |
|||
const height = computed(() => { |
|||
return window.outerHeight * heightCoefficient.value; |
|||
}); |
|||
const top = computed(() => { |
|||
return window.outerHeight * ((1.0 - heightCoefficient.value - 0.15) / 2); |
|||
}); |
|||
const left = computed(() => { |
|||
return (window.outerWidth * (1.0 - widthCoefficient.value)) / 2; |
|||
}); |
|||
// 雷达名称 |
|||
let name = ref(''); |
|||
// 所属区域列表 |
|||
let areaList = ref([]); |
|||
// 选中所属区域 |
|||
let selectArea: any = ref(null); |
|||
// 主机设备列表 |
|||
let hostDeviceList = ref([]); |
|||
// 选中的主机设备 |
|||
let selectHostDevice: any = ref(null); |
|||
// 设备编码 |
|||
let selectDeviceNum = ref(null); |
|||
// 上传图片文件 |
|||
let uploadFile:any = ref(null); |
|||
// 上传图片路径 |
|||
let previewImgUrl = ref(''); |
|||
// 设置上传次数 |
|||
let uploadFileCount = ref(1); |
|||
// 定时器 |
|||
let timer: any = ref(null); |
|||
// 是否有更新模型 |
|||
let isUpdateModel = ref(false); |
|||
// 取消还原数据 |
|||
let revert = ref(null); |
|||
// 当前模型 |
|||
let currentModel: any = ref(null); |
|||
// 俯仰角度 |
|||
let LngLatHeight = ref([0, 0, 0]); |
|||
// 扫描颜色 |
|||
let radarColor = ref({ rgba: { r: 0, g: 255, b: 0, a: 0.5 } }); |
|||
// 法线偏移角度 |
|||
let radarShifting = ref(1); |
|||
// 扫描范围 |
|||
let radarRange = ref(100); |
|||
// 扫描半径 |
|||
let radarRadius = ref(500); |
|||
// 雷达扫描编辑、取消使用 |
|||
let radarOldObj: any = ref({}); |
|||
// 提交对象 |
|||
let submitObject: any = ref({}); |
|||
// 窗口显示或隐藏 |
|||
let winVisible = ref(true); |
|||
// 是否跟随鼠标状态 |
|||
let creating = ref(false); |
|||
// 是否可见 |
|||
let show = ref(false); |
|||
// 是否展开表单项 |
|||
let expand = ref(true); |
|||
|
|||
// 监听图片上传 |
|||
watch(uploadFile, (newVal, _oldVal) => { |
|||
// 模拟表单提交的对象 |
|||
let formData = new FormData(); |
|||
// 设置上传目录为temp |
|||
formData.append('biz', 'temp'); |
|||
// 设置上传文件 |
|||
formData.append('file', newVal); |
|||
// 进行上传等待响应 |
|||
defHttp.post({ url: '/sys/common/upload', params: formData }, { isTransformResponse: false }).then((response) => { |
|||
// 响应并成功操作 |
|||
if (response.success) { |
|||
// 设置图片显示地址 |
|||
let imageUrl = '/dt/sys/common/static/' + response.message; |
|||
// 设置img dom元素src预览地址 |
|||
previewImgUrl.value = imageUrl; |
|||
// 设置地图中pin的图片地址 |
|||
currentModel.value.imageUrl = imageUrl; |
|||
if (!isUpdateModel.value && uploadFileCount.value == 1) { |
|||
// 设置pin展示 |
|||
show.value = true; |
|||
// 设置为编辑状态 |
|||
creating.value = true; |
|||
// 上传次数变成2 |
|||
uploadFileCount.value++; |
|||
} |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
// 获取区域数据 |
|||
function getAreas() { |
|||
const submitData: any = { |
|||
pageNo: 1, |
|||
pageSize: 999, |
|||
}; |
|||
return defHttp |
|||
.get( |
|||
{ |
|||
url: '/military/msMapLine/list', |
|||
params: submitData, |
|||
}, |
|||
{ isTransformResponse: false } |
|||
) |
|||
.then((res) => { |
|||
if (res.success) { |
|||
areaList.value = res.result.records; |
|||
} |
|||
}); |
|||
} |
|||
// 获取主机设备 |
|||
function getHostDeviceList() { |
|||
const url = '/military/dtDeviceInfo/list'; |
|||
const args = { pageNo: 1, pageSize: 999 }; |
|||
return defHttp |
|||
.get({ url, params: args }, { isTransformResponse: false }) |
|||
.then((reponse) => { |
|||
if (reponse.success) { |
|||
hostDeviceList.value = reponse.result.records; |
|||
} |
|||
}) |
|||
.catch(() => { |
|||
throw '获取主机信息错误'; |
|||
}); |
|||
} |
|||
// 名称修改的变化事件 |
|||
function nameChange(model) { |
|||
// pin类型的名称变化时修改显示的文字 |
|||
model.pinBuilder.extText = name.value; |
|||
} |
|||
// 修改属性状态,取反 |
|||
function modelState(propName) { |
|||
proxy[propName] = !proxy[propName]; |
|||
} |
|||
// 添加pin(雷达) |
|||
function addPin() { |
|||
// 创建pin |
|||
const pin = new window.XE.Obj.Pin(window.$earth); |
|||
// 设置缩放 |
|||
pin.scale = 0.8; |
|||
// 设置url |
|||
pin.imageUrl = ''; |
|||
// 设置最大可视距离 |
|||
pin.far = 1073741824; |
|||
// 设置显示文字样式 |
|||
pin.pinBuilder.extTextFont = '30px 楷体'; |
|||
pin.pinBuilder.extTextPixelOffset = [30, -20]; |
|||
pin.pinBuilder.fillColor = [1, 1, 1, 0.9]; |
|||
pin.pinBuilder.outlineColor = [0, 0, 0, 0.9]; |
|||
//移入移出事件 |
|||
pin.onmouseover = () => { |
|||
window.$earth.czm.viewer._container.style.cursor = 'pointer'; |
|||
}; |
|||
pin.onmouseout = () => { |
|||
window.$earth.czm.viewer._container.style.cursor = 'default'; |
|||
}; |
|||
// 绑定属性 |
|||
bindPinProps(pin); |
|||
// 设置为不可见 |
|||
show.value = false; |
|||
// 刷新窗体 |
|||
modelState('creating'); |
|||
|
|||
return pin; |
|||
} |
|||
// 绑定模型属性 |
|||
function bindPinProps(pin) { |
|||
pin.disposers.push(window.XE.MVVM.bindPosition(proxy, 'LngLatHeight', pin, 'position')); |
|||
pin.disposers.push(window.XE.MVVM.bind(proxy, 'creating', pin, 'creating')); |
|||
pin.disposers.push(window.XE.MVVM.bind(proxy, 'show', pin, 'show')); |
|||
} |
|||
// 取消 |
|||
function cancel() { |
|||
if (isUpdateModel.value) { |
|||
// 调用更新时的取消 |
|||
updateClose(); |
|||
} else { |
|||
// 调用创建时的取消 |
|||
close(); |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addRadarComShow = false; |
|||
} |
|||
// 更新时的取消方法 |
|||
function updateClose() { |
|||
// 还原数据 |
|||
if (currentModel.value) { |
|||
currentModel.value.xbsjFromJSON(revert.value); |
|||
if (Object.keys(radarOldObj.value).length > 0) { |
|||
radarColor.value.rgba = radarOldObj.value.color; |
|||
radarRadius.value = radarOldObj.value.radarRadius; |
|||
radarRange.value = radarOldObj.value.radarRange; |
|||
radarShifting.value = radarOldObj.value.radarShifting; |
|||
} |
|||
currentModel.value.editing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value.rotationEditing = false; |
|||
} |
|||
} |
|||
// 创建时的取消方法 |
|||
function close() { |
|||
// 模型不为空时,销毁模型 |
|||
if (currentModel.value) { |
|||
if (currentModel.value.addViewShedReturn) { |
|||
console.log('window.$earth.czm.viewer.entities', window.$earth.czm.viewer.entities); |
|||
window.$earth.czm.viewer.entities.remove(currentModel.value.addViewShedReturn); |
|||
} |
|||
currentModel.value.addViewShedReturn = undefined; |
|||
currentModel.value.editing = false; |
|||
currentModel.value.destroy(); |
|||
} |
|||
} |
|||
// 确定 |
|||
function ok() { |
|||
// pin类型图片效验 |
|||
if (currentModel.value.imageUrl.length <= 0) { |
|||
createMessage.warning('需要先上传图片', 2); |
|||
return; |
|||
} else if (!selectHostDevice.value) { |
|||
createMessage.warning('主机设备不能为空', 2); |
|||
return; |
|||
} else if (!selectDeviceNum.value) { |
|||
createMessage.warning('设备编码不能为空', 2); |
|||
return; |
|||
} else if (selectArea.value == null || selectArea.value.id <= 0) { |
|||
// 非区域类型,区域效验 |
|||
createMessage.warning('请选择所属区域', 2); |
|||
return; |
|||
} |
|||
// 关闭编辑状态 |
|||
currentModel.value.editing = false; |
|||
// 提交数据 |
|||
submitData(); |
|||
} |
|||
// 提交数据方法 |
|||
function submitData() { |
|||
const lastIndex = currentModel.value.imageUrl.lastIndexOf('/temp'); |
|||
const ImgUrl = currentModel.value.imageUrl.substring(lastIndex + 1); |
|||
// 当前模型为Pin类型 |
|||
// 更具创建时选择的模型类型判断,赋予模型类型标识 |
|||
const labelAttr = 4; // 雷达字典编号4 微波字典编号10 |
|||
submitObject.value = { |
|||
mapLabel: { |
|||
id: null, |
|||
createBy: null, |
|||
createTime: null, |
|||
updateBy: null, |
|||
updateTime: null, |
|||
sysOrgCode: null, |
|||
labelAttr: labelAttr, // 类型标识 |
|||
labelName: name.value, // 名称 |
|||
lineId: selectArea.value?.id ? selectArea.value.id : null, // 所属区域 |
|||
labelLon: LngLatHeight.value[0], // x坐标 |
|||
labelLat: LngLatHeight.value[1], // y坐标 |
|||
labelHeight: LngLatHeight.value[2], // z坐标 |
|||
labelImgUrl: ImgUrl, // 设置url |
|||
labelStatus: 1, // 启动:1 不启用 0 |
|||
labelCode: selectDeviceNum.value, |
|||
cameraId: null, |
|||
cameraName: null, |
|||
pan: 0, |
|||
tile: 0, |
|||
zoom: 0, |
|||
placements: null, |
|||
}, |
|||
deviceId: selectHostDevice.value.id, |
|||
}; |
|||
let request: any = null; |
|||
// 提交地址 |
|||
let url = ''; |
|||
if (isUpdateModel.value) { |
|||
// 设置url为编辑地址,设置方法为put 设置记录id |
|||
url = '/military/msMapLabel/editMapLabel'; |
|||
// submitObject.value.mapLabel.id = props.eidtId; |
|||
request = defHttp.put({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} else { |
|||
// 设置url为新增地址,设置方法为post |
|||
url = '/military/msMapLabel/addMapLabel'; |
|||
request = defHttp.post({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} |
|||
const { setLabelStatus } = props; |
|||
// 提交数据,等待回复 |
|||
request |
|||
.then(function (response) { |
|||
// 数据回复,并成功 |
|||
if (response.success) { |
|||
// 设置显示节点的ref为 node_ref |
|||
const lineId = 'node_' + selectArea.value.id; |
|||
// const ldLineId = 'nodeSecondary_' + selectArea.value.id; |
|||
|
|||
// 该区域的微波集合 |
|||
const wbParent = window.$earth.sceneTree.$refs[lineId] && window.$earth.sceneTree.$refs[lineId].children[2]; |
|||
// 该区域的雷达集合 |
|||
const ldParent = window.$earth.sceneTree.$refs[lineId] && window.$earth.sceneTree.$refs[lineId].children[1]; |
|||
// 创建叶子节点 |
|||
let node = new window.XE.SceneTree.Leaf(currentModel.value); |
|||
// 设置节点显示名称 |
|||
node.title = name.value; |
|||
// 设置节点ref |
|||
node.ref = response.result; |
|||
// name属性用来记录区域id |
|||
node.name = submitObject.value.lineId; |
|||
// 用户属性用来记录标志类型 |
|||
currentModel.value.customProp = |
|||
'{"labelAttr":' + labelAttr + ',"labelCode":"' + selectDeviceNum.value + '","deviceId":"' + selectHostDevice.value.id + '"}'; |
|||
setLabelStatus(selectHostDevice.value, selectDeviceNum.value, node.ref, 2).finally(() => { |
|||
if (labelAttr == 4) { |
|||
// 雷达新增一圆 |
|||
ldParent.children.push(node); |
|||
} else { |
|||
// 微波新增一圆 |
|||
wbParent.children.push(node); |
|||
} |
|||
// 提示用户 |
|||
createMessage.success('添加成功!', 2); |
|||
}); |
|||
|
|||
//是否为雷达 |
|||
if (labelAttr == 4) { |
|||
let radarObj = { |
|||
radarCode: selectDeviceNum.value, |
|||
elevation: Number(radarRange.value), |
|||
workingRadius: Number(radarRadius.value), |
|||
angularRadian: Number(radarShifting.value), |
|||
customProp: JSON.stringify({ color: radarColor.value.rgba }), |
|||
}; |
|||
defHttp.post({ url: '/military/RadarConfig/add', params: radarObj }, { isTransformResponse: false }); |
|||
} |
|||
} |
|||
}) |
|||
.then(function () { |
|||
finish(); |
|||
}); |
|||
} |
|||
// 提交完成 |
|||
function finish() { |
|||
if (currentModel.value) { |
|||
// 释放当前模型的引用 |
|||
currentModel.value.rotationEditing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value = null; |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addRadarComShow = false; |
|||
} |
|||
// 雷达扫描 |
|||
function getRadarScan() { |
|||
if (timer.value) clearTimeout(timer.value); |
|||
timer.value = setTimeout(() => { |
|||
let rgb = radarColor.value.rgba; |
|||
if (currentModel.value.addViewShedReturn) { |
|||
console.log('window.$earth.czm.viewer.entities', window.$earth.czm.viewer.entities); |
|||
window.$earth.czm.viewer.entities.remove(currentModel.value.addViewShedReturn); |
|||
} |
|||
//计算偏移角 |
|||
let left = Number(radarShifting.value) - Number(radarRange.value) / 2; |
|||
currentModel.value.addViewShedReturn = addViewShedRadar( |
|||
currentModel.value.position, |
|||
radarRadius.value, |
|||
left, |
|||
Number(radarRange.value) / 2 + Number(radarShifting.value), |
|||
[rgb.r / 255, rgb.g / 255, rgb.b / 255, rgb.a] |
|||
); |
|||
}, 300); |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// 设置当前状态为添加 |
|||
isUpdateModel.value = false; |
|||
// 获取主机设备 |
|||
getHostDeviceList().then(() => { |
|||
// 获取区域数据 |
|||
getAreas().then(() => { |
|||
// 折叠面板 |
|||
expand.value = true; |
|||
// 创建并绑定模型 |
|||
currentModel.value = addPin(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
return { |
|||
width, |
|||
height, |
|||
top, |
|||
left, |
|||
name, |
|||
areaList, |
|||
selectArea, |
|||
hostDeviceList, |
|||
selectHostDevice, |
|||
selectDeviceNum, |
|||
uploadFile, |
|||
previewImgUrl, |
|||
isUpdateModel, |
|||
LngLatHeight, |
|||
radarShifting, |
|||
radarColor, |
|||
radarRange, |
|||
radarRadius, |
|||
radarOldObj, |
|||
currentModel, |
|||
winVisible, |
|||
creating, |
|||
expand, |
|||
modelState, |
|||
getRadarScan, |
|||
nameChange, |
|||
cancel, |
|||
ok, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style scoped> |
|||
.object-box { |
|||
width: 100%; |
|||
height: 86%; |
|||
|
|||
label { |
|||
color: #ffffff; |
|||
} |
|||
} |
|||
:deep(.custom-item-box > div > input) { |
|||
width: 45% !important; |
|||
margin-right: 0% !important; |
|||
} |
|||
:deep(.custom-label) { |
|||
width: 16% !important; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
color: #ffffff; |
|||
} |
|||
:deep(.object-box .custom-item) { |
|||
height: 10%; |
|||
margin-top: 2%; |
|||
} |
|||
:deep(.custom-item-box) { |
|||
padding-left: 5% !important; |
|||
width: 80% !important; |
|||
} |
|||
.name-input { |
|||
height: 90%; |
|||
width: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
.xyz-input { |
|||
height: 90%; |
|||
width: 30%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
|
|||
.y-margin { |
|||
margin-left: 5%; |
|||
margin-right: 5%; |
|||
} |
|||
.edit-model-btn { |
|||
cursor: pointer; |
|||
line-height: 5%; |
|||
} |
|||
|
|||
.edit-model-btn-disable { |
|||
cursor: not-allowed; |
|||
} |
|||
.upload-box { |
|||
height: 100%; |
|||
width: 20%; |
|||
} |
|||
</style> |
@ -0,0 +1,542 @@ |
|||
<!-- |
|||
* @Author: Fuyuu 1805498209@qq.com |
|||
* @Date: 2024-01-10 15:19:50 |
|||
* @LastEditors: Fuyuu 1805498209@qq.com |
|||
* @LastEditTime: 2024-01-11 15:49:37 |
|||
* @FilePath: \dt-admin-pc-v2\src\components\earthMap\toolbar\AddWaveCom.vue |
|||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE |
|||
--> |
|||
<template> |
|||
<div class="create-model-modal" v-if="winVisible"> |
|||
<Window |
|||
:title="title" |
|||
@cancel="cancel" |
|||
@ok="ok" |
|||
:width="width" |
|||
:minWidth="600" |
|||
:height="height" |
|||
:left="left" |
|||
:top="top" |
|||
:floatright="false" |
|||
:footervisible="true" |
|||
v-show="!creating" |
|||
:expand="expand" |
|||
> |
|||
<div class="object-box"> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">微波名称:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="name" class="name-input" style="height: 90%; width: 100%" @change="nameChange(currentModel)" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">所属区域:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjSelect id="area-select" title="name" :list="areaList" v-model:value="selectArea" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">主机设备:</label> |
|||
<div class="custom-item-box"> |
|||
<XbsjSelect title="deviceName" :list="hostDeviceList" v-model:value="selectHostDevice" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">设备编码:</label> |
|||
<div class="custom-item-box"> |
|||
<input v-model="selectDeviceNum" class="name-input" style="height: 90%; width: 100%" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex; height: 20%" class="custom-item"> |
|||
<label class="custom-label">上传图标:</label> |
|||
<div class="custom-item-box"> |
|||
<div class="upload-box"> |
|||
<upload v-model:file="uploadFile" :pre-view-url="previewImgUrl" :isUpdateModel="isUpdateModel" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex" class="custom-item"> |
|||
<label class="custom-label">经纬度:</label> |
|||
<div class="custom-item-box"> |
|||
<!-- <XbsjLngLatHeight v-model="LngLatHeight" style="height: 90%; width: 100%"></XbsjLngLatHeight> --> |
|||
<input v-model="LngLatHeight[0]" type="number" class="xyz-input" /> |
|||
<input v-model="LngLatHeight[1]" type="number" class="xyz-input y-margin" /> |
|||
<input v-model="LngLatHeight[2]" type="number" class="xyz-input" /> |
|||
</div> |
|||
</div> |
|||
<div style="display: flex; justify-content: center" class="custom-item"> |
|||
<button |
|||
@click="modelState('creating')" |
|||
:class="['xbsj-button', 'edit-model-btn', creating ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%; display: flex; align-items: center; justify-content: center" |
|||
> |
|||
拾取 |
|||
</button> |
|||
<button |
|||
@click="currentModel.editing = true" |
|||
:class="['xbsj-button', 'edit-model-btn', creating ? 'edit-model-btn-disable' : '']" |
|||
:disabled="creating" |
|||
style="width: 20%; display: flex; align-items: center; justify-content: center" |
|||
> |
|||
移动 |
|||
</button> |
|||
</div> |
|||
</div> |
|||
</Window> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { onMounted, defineComponent, ref, getCurrentInstance, computed, watch } from 'vue'; |
|||
import xbsjScale from '/@/components/earthMap/components/xbsjScale.vue'; |
|||
import XbsjSelect from '/@/components/earthMap/components/XbsjSelect.vue'; |
|||
import XbsjColorButton from '/@/components/earthMap/components/XbsjColorButton.vue'; |
|||
import upload from '/@/components/earthMap/components/upload.vue'; |
|||
import Window from '@/components/earthMap/components/Window.vue'; |
|||
import { defHttp } from '/@/utils/http/axios'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
|
|||
export default defineComponent({ |
|||
name: 'AddWaveCom', |
|||
components: { |
|||
xbsjScale, |
|||
XbsjSelect, |
|||
upload, |
|||
XbsjColorButton, |
|||
Window, |
|||
}, |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '添加微波探测器', |
|||
}, |
|||
setLabelStatus: { |
|||
type: Function, |
|||
default: null, |
|||
}, |
|||
setIconByRef: { |
|||
type: Function, |
|||
default: null, |
|||
}, |
|||
el: { |
|||
type: Object, |
|||
default: null, |
|||
}, |
|||
}, |
|||
setup(props) { |
|||
const { proxy }: any = getCurrentInstance(); |
|||
const { createMessage } = useMessage(); |
|||
// 宽高 |
|||
let widthCoefficient = ref(0.3); |
|||
let heightCoefficient = ref(0.5); |
|||
// 计算弹窗宽高定位 |
|||
const width = computed(() => { |
|||
return window.outerWidth * widthCoefficient.value; |
|||
}); |
|||
const height = computed(() => { |
|||
return window.outerHeight * heightCoefficient.value; |
|||
}); |
|||
const top = computed(() => { |
|||
return window.outerHeight * ((1.0 - heightCoefficient.value - 0.15) / 2); |
|||
}); |
|||
const left = computed(() => { |
|||
return (window.outerWidth * (1.0 - widthCoefficient.value)) / 2; |
|||
}); |
|||
// 微波名称 |
|||
let name = ref(''); |
|||
// 所属区域列表 |
|||
let areaList = ref([]); |
|||
// 选中所属区域 |
|||
let selectArea: any = ref(null); |
|||
// 主机设备列表 |
|||
let hostDeviceList = ref([]); |
|||
// 选中的主机设备 |
|||
let selectHostDevice: any = ref(null); |
|||
// 设备编码 |
|||
let selectDeviceNum = ref(null); |
|||
// 上传图片文件 |
|||
let uploadFile: any = ref(null); |
|||
// 上传图片路径 |
|||
let previewImgUrl = ref(''); |
|||
// 设置上传次数 |
|||
let uploadFileCount = ref(1); |
|||
// 是否有更新模型 |
|||
let isUpdateModel = ref(false); |
|||
// 取消还原数据 |
|||
let revert = ref(null); |
|||
// 当前模型 |
|||
let currentModel: any = ref(null); |
|||
// 俯仰角度 |
|||
let LngLatHeight = ref([0, 0, 0]); |
|||
// 提交对象 |
|||
let submitObject: any = ref({}); |
|||
// 窗口显示或隐藏 |
|||
let winVisible = ref(true); |
|||
// 是否跟随鼠标状态 |
|||
let creating = ref(false); |
|||
// 是否可见 |
|||
let show = ref(false); |
|||
// 是否展开表单项 |
|||
let expand = ref(true); |
|||
|
|||
watch(uploadFile, (newVal, _oldVal) => { |
|||
// 模拟表单提交的对象 |
|||
let formData = new FormData(); |
|||
// 设置上传目录为temp |
|||
formData.append('biz', 'temp'); |
|||
// 设置上传文件 |
|||
formData.append('file', newVal); |
|||
// 进行上传等待响应 |
|||
defHttp.post({ url: '/sys/common/upload', params: formData }, { isTransformResponse: false }).then((response) => { |
|||
// 响应并成功操作 |
|||
if (response.success) { |
|||
// 设置图片显示地址 |
|||
let imageUrl = '/dt/sys/common/static/' + response.message; |
|||
// 设置img dom元素src预览地址 |
|||
previewImgUrl.value = imageUrl; |
|||
// 设置地图中pin的图片地址 |
|||
currentModel.value.imageUrl = imageUrl; |
|||
if (!isUpdateModel.value && uploadFileCount.value == 1) { |
|||
// 设置pin展示 |
|||
show.value = true; |
|||
// 设置为编辑状态 |
|||
creating.value = true; |
|||
// 上传次数变成2 |
|||
uploadFileCount.value++; |
|||
} |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
// 获取区域数据 |
|||
function getAreas() { |
|||
const submitData: any = { |
|||
pageNo: 1, |
|||
pageSize: 999, |
|||
}; |
|||
return defHttp |
|||
.get( |
|||
{ |
|||
url: '/military/msMapLine/list', |
|||
params: submitData, |
|||
}, |
|||
{ isTransformResponse: false } |
|||
) |
|||
.then((res) => { |
|||
if (res.success) { |
|||
areaList.value = res.result.records; |
|||
} |
|||
}); |
|||
} |
|||
// 获取主机设备 |
|||
function getHostDeviceList() { |
|||
const url = '/military/dtDeviceInfo/list'; |
|||
const args = { pageNo: 1, pageSize: 999 }; |
|||
return defHttp |
|||
.get({ url, params: args }, { isTransformResponse: false }) |
|||
.then((reponse) => { |
|||
if (reponse.success) { |
|||
hostDeviceList.value = reponse.result.records; |
|||
} |
|||
}) |
|||
.catch(() => { |
|||
throw '获取主机信息错误'; |
|||
}); |
|||
} |
|||
// 名称修改的变化事件 |
|||
function nameChange(model) { |
|||
// pin类型的名称变化时修改显示的文字 |
|||
model.pinBuilder.extText = name.value; |
|||
} |
|||
// 修改属性状态,取反 |
|||
function modelState(propName) { |
|||
proxy[propName] = !proxy[propName]; |
|||
} |
|||
// 添加pin(微波) |
|||
function addPin() { |
|||
// 创建pin |
|||
const pin = new window.XE.Obj.Pin(window.$earth); |
|||
// 设置缩放 |
|||
pin.scale = 0.8; |
|||
// 设置url |
|||
pin.imageUrl = ''; |
|||
// 设置最大可视距离 |
|||
pin.far = 1073741824; |
|||
// 设置显示文字样式 |
|||
pin.pinBuilder.extTextFont = '30px 楷体'; |
|||
pin.pinBuilder.extTextPixelOffset = [30, -20]; |
|||
pin.pinBuilder.fillColor = [1, 1, 1, 0.9]; |
|||
pin.pinBuilder.outlineColor = [0, 0, 0, 0.9]; |
|||
// 绑定属性 |
|||
bindPinProps(pin); |
|||
// 设置为不可见 |
|||
show.value = false; |
|||
// 刷新窗体 |
|||
modelState('creating'); |
|||
modelState('creating'); |
|||
return pin; |
|||
} |
|||
// 绑定模型属性 |
|||
function bindPinProps(pin) { |
|||
pin.disposers.push(window.XE.MVVM.bindPosition(proxy, 'LngLatHeight', pin, 'position')); |
|||
pin.disposers.push(window.XE.MVVM.bind(proxy, 'creating', pin, 'creating')); |
|||
pin.disposers.push(window.XE.MVVM.bind(proxy, 'show', pin, 'show')); |
|||
} |
|||
// 取消 |
|||
function cancel() { |
|||
if (isUpdateModel.value) { |
|||
// 调用更新时的取消 |
|||
updateClose(); |
|||
} else { |
|||
// 调用创建时的取消 |
|||
close(); |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addWaveComShow = false; |
|||
} |
|||
// 更新时的取消方法 |
|||
function updateClose() { |
|||
// 还原数据 |
|||
if (currentModel.value) { |
|||
currentModel.value.xbsjFromJSON(revert.value); |
|||
currentModel.value.editing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value.rotationEditing = false; |
|||
} |
|||
} |
|||
// 创建时的取消方法 |
|||
function close() { |
|||
// 模型不为空时,销毁模型 |
|||
if (currentModel.value) { |
|||
if (currentModel.value.addViewShedReturn) { |
|||
window.$earth.czm.viewer.entities.remove(currentModel.value.addViewShedReturn); |
|||
} |
|||
currentModel.value.editing = false; |
|||
currentModel.value.destroy(); |
|||
} |
|||
} |
|||
// 确定 |
|||
function ok() { |
|||
// pin类型图片效验 |
|||
if (currentModel.value.imageUrl.length <= 0) { |
|||
createMessage.warning('需要先上传图片', 2); |
|||
return; |
|||
} else if (!selectHostDevice.value) { |
|||
createMessage.warning('主机设备不能为空', 2); |
|||
return; |
|||
} else if (!selectDeviceNum.value) { |
|||
createMessage.warning('设备编码不能为空', 2); |
|||
return; |
|||
} else if (selectArea.value == null || selectArea.value.id <= 0) { |
|||
// 非区域类型,区域效验 |
|||
createMessage.warning('请选择所属区域', 2); |
|||
return; |
|||
} |
|||
// 关闭编辑状态 |
|||
currentModel.value.editing = false; |
|||
// 提交数据 |
|||
submitData(); |
|||
} |
|||
// 提交数据方法 |
|||
function submitData() { |
|||
const lastIndex = currentModel.value.imageUrl.lastIndexOf('/temp'); |
|||
const ImgUrl = currentModel.value.imageUrl.substring(lastIndex + 1); |
|||
// 当前模型为Pin类型 |
|||
// 更具创建时选择的模型类型判断,赋予模型类型标识 |
|||
const labelAttr = 10; // 雷达字典编号4 微波字典编号10 |
|||
submitObject.value = { |
|||
mapLabel: { |
|||
id: null, |
|||
createBy: null, |
|||
createTime: null, |
|||
updateBy: null, |
|||
updateTime: null, |
|||
sysOrgCode: null, |
|||
labelAttr: labelAttr, // 类型标识 |
|||
labelName: name.value, // 名称 |
|||
lineId: selectArea.value?.id ? selectArea.value.id : null, // 所属区域 |
|||
labelLon: LngLatHeight.value[0], // x坐标 |
|||
labelLat: LngLatHeight.value[1], // y坐标 |
|||
labelHeight: LngLatHeight.value[2], // z坐标 |
|||
labelImgUrl: ImgUrl, // 设置url |
|||
labelStatus: 1, // 启动:1 不启用 0 |
|||
labelCode: selectDeviceNum.value, |
|||
cameraId: null, |
|||
cameraName: null, |
|||
pan: 0, |
|||
tile: 0, |
|||
zoom: 0, |
|||
placements: null, |
|||
}, |
|||
deviceId: selectHostDevice.value.id, |
|||
}; |
|||
let request: any = null; |
|||
// 提交地址 |
|||
let url = ''; |
|||
if (isUpdateModel.value) { |
|||
// 设置url为编辑地址,设置方法为put 设置记录id |
|||
url = '/military/msMapLabel/editMapLabel'; |
|||
// submitObject.value.mapLabel.id = props.eidtId; |
|||
request = defHttp.put({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} else { |
|||
// 设置url为新增地址,设置方法为post |
|||
url = '/military/msMapLabel/addMapLabel'; |
|||
request = defHttp.post({ url: url, params: submitObject.value }, { isTransformResponse: false }); |
|||
} |
|||
const { setLabelStatus } = props; |
|||
// 提交数据,等待回复 |
|||
request |
|||
.then(function (response) { |
|||
// 数据回复,并成功 |
|||
if (response.success) { |
|||
// 设置显示节点的ref为 node_ref |
|||
const lineId = 'node_' + selectArea.value.id; |
|||
// const ldLineId = 'nodeSecondary_' + selectArea.value.id; |
|||
|
|||
// 该区域的微波集合 |
|||
const wbParent = window.$earth.sceneTree.$refs[lineId] && window.$earth.sceneTree.$refs[lineId].children[2]; |
|||
// 该区域的雷达集合 |
|||
// const ldParent = window.$earth.sceneTree.$refs[ldLineId]; |
|||
// 创建叶子节点 |
|||
let node = new window.XE.SceneTree.Leaf(currentModel.value); |
|||
// 设置节点显示名称 |
|||
node.title = name.value; |
|||
// 设置节点ref |
|||
node.ref = response.result; |
|||
// name属性用来记录区域id |
|||
node.name = submitObject.value.lineId; |
|||
// 用户属性用来记录标志类型 |
|||
currentModel.value.customProp = |
|||
'{"labelAttr":' + labelAttr + ',"labelCode":"' + selectDeviceNum.value + '","deviceId":"' + selectHostDevice.value.id + '"}'; |
|||
setLabelStatus(selectHostDevice.value, selectDeviceNum.value, node.ref, 2).finally(() => { |
|||
// 微波新增一圆 |
|||
wbParent.children.push(node); |
|||
// 提示用户 |
|||
createMessage.success('添加成功!', 2); |
|||
}); |
|||
} |
|||
}) |
|||
.then(function () { |
|||
finish(); |
|||
}); |
|||
} |
|||
// 提交完成 |
|||
function finish() { |
|||
if (currentModel.value) { |
|||
// 释放当前模型的引用 |
|||
currentModel.value.rotationEditing = false; |
|||
currentModel.value.positionEditing = false; |
|||
currentModel.value = null; |
|||
} |
|||
//通过父组件v-if 关闭本组件 |
|||
proxy.$parent.addWaveComShow = false; |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// 设置当前状态为添加 |
|||
isUpdateModel.value = false; |
|||
// 获取主机设备 |
|||
getHostDeviceList().then(() => { |
|||
// 获取区域数据 |
|||
getAreas().then(() => { |
|||
// 折叠面板 |
|||
expand.value = true; |
|||
// 创建并绑定模型 |
|||
currentModel.value = addPin(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
return { |
|||
width, |
|||
height, |
|||
top, |
|||
left, |
|||
name, |
|||
areaList, |
|||
selectArea, |
|||
hostDeviceList, |
|||
selectHostDevice, |
|||
selectDeviceNum, |
|||
uploadFile, |
|||
previewImgUrl, |
|||
isUpdateModel, |
|||
LngLatHeight, |
|||
currentModel, |
|||
winVisible, |
|||
creating, |
|||
expand, |
|||
modelState, |
|||
nameChange, |
|||
cancel, |
|||
ok, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
<style scoped> |
|||
.object-box { |
|||
width: 100%; |
|||
height: 86%; |
|||
|
|||
label { |
|||
color: #ffffff; |
|||
} |
|||
} |
|||
:deep(.custom-item-box > div > input) { |
|||
width: 45% !important; |
|||
margin-right: 0% !important; |
|||
} |
|||
:deep(.custom-label) { |
|||
width: 15% !important; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
color: #ffffff; |
|||
} |
|||
:deep(.object-box .custom-item) { |
|||
height: 10%; |
|||
margin-top: 2%; |
|||
} |
|||
:deep(.custom-item-box) { |
|||
padding-left: 5% !important; |
|||
width: 80% !important; |
|||
} |
|||
.name-input { |
|||
height: 90%; |
|||
width: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
.xyz-input { |
|||
height: 90%; |
|||
width: 30%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
border-radius: 3px; |
|||
border: none; |
|||
color: #ddd; |
|||
padding: 5px; |
|||
outline: none; |
|||
} |
|||
|
|||
.y-margin { |
|||
margin-left: 5%; |
|||
margin-right: 5%; |
|||
} |
|||
.edit-model-btn { |
|||
cursor: pointer; |
|||
line-height: 5%; |
|||
} |
|||
|
|||
.edit-model-btn-disable { |
|||
cursor: not-allowed; |
|||
} |
|||
.upload-box { |
|||
height: 100%; |
|||
width: 20%; |
|||
} |
|||
</style> |
Loading…
Reference in new issue