You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
10 KiB
336 lines
10 KiB
1 year ago
|
<template>
|
||
|
<div>
|
||
|
<a-row :gutter="[0, 16]">
|
||
|
<!-- <a-col :span="11" :offset="1">
|
||
|
<div>场景编号:</div>
|
||
|
<a-input class="inputWidthCss1" v-model:value="subObject.sceneCode" :disabled="true"></a-input>
|
||
|
</a-col> -->
|
||
|
<a-col :span="23">
|
||
|
<slot name="header"></slot>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>站点名称:</div>
|
||
|
<a-input class="inputWidthCss1" v-model:value="subObject.sceneName" placeholder="请输入场景编号名称"
|
||
|
:disabled="disable"></a-input>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>站点视距:</div>
|
||
|
<a-input-number class="inputWidthCss1" v-model:value="subObject.viewDistance"
|
||
|
:disabled="disable"></a-input-number>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>站点类型:</div>
|
||
|
<a-select v-model:value="subObject.sceneType" :disabled="disable">
|
||
|
<template :key="Number(sceneType.value)" v-for="sceneType in sceneTypes">
|
||
|
<a-select-option :value="Number(sceneType.value)">{{ sceneType.text }}</a-select-option>
|
||
|
</template>
|
||
|
|
||
|
</a-select>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>飞入时间:</div>
|
||
|
<a-input-number class="inputWidthCss1" v-model:value="subObject.duration" :disabled="disable"></a-input-number>
|
||
|
</a-col>
|
||
|
|
||
|
<!-- <a-col :span="11" :offset="1">
|
||
|
<div>所属区域:</div>
|
||
|
<j-dict-select-tag class="inputWidthCss1" placeholder="请选择场景类型" v-model:value="subObject.sceneType"
|
||
|
dictCode="SceneType" />
|
||
|
</a-col> -->
|
||
|
|
||
|
<!-- <a-col :span="11" :offset="1">
|
||
|
<div>父场景编号:</div>
|
||
|
<a-select v-model:value="subObject.parentSceneCode" :show-search="true" :filterOption="filterOption">
|
||
|
<a-select-option :value="parentCode" v-for="parentCode in parentCodeArr">{{ parentCode }}</a-select-option>
|
||
|
</a-select>
|
||
|
</a-col> -->
|
||
|
<a-col :span="22" :offset="1">
|
||
|
<div class="centerText">拾取中心坐标和相机数据<img :src="locationPng" class="dwImg" @click="mapShow" /></div>
|
||
|
</a-col>
|
||
|
<!-- <a-col :span="11" :offset="1">
|
||
|
<div class="centerText">旋转<img :src="locationPng" class="dwImg" @click="mapShow" /></div>
|
||
|
</a-col> -->
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>
|
||
|
<div>中心经度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.lon" :disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>中心纬度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.lat" :disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>中心高度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.altitude" :disabled="disable" />
|
||
|
</div>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>
|
||
|
<div>相机经度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.cameraLon"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>相机纬度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.cameraLat"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>相机高度:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.cameraAltitude"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>站点图标:</div>
|
||
|
<a-upload name="avatar" list-type="picture-card" class="avatar-uploader" :show-upload-list="false"
|
||
|
:customRequest="preViewOk" :before-upload="preBeforeUpload" :accept="previewType.toString()"
|
||
|
:disabled="disable">
|
||
|
<img v-if="preViewUrl" :src="subObject.icon" alt="avatar" class="preViewImg"
|
||
|
style="width:102px;height:102px;object-fit: contain;" />
|
||
|
<div v-else>
|
||
|
<div class="ant-upload-text">上传图标</div>
|
||
|
</div>
|
||
|
</a-upload>
|
||
|
</a-col>
|
||
|
<a-col :span="11" :offset="1">
|
||
|
<div>
|
||
|
<div>相机偏航角:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.rotationX"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>相机俯仰角:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.rotationY"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
<div>
|
||
|
<div>相机翻转角:</div><a-input-number class="inputWidthCss1" v-model:value="subObject.rotationZ"
|
||
|
:disabled="disable" />
|
||
|
</div>
|
||
|
</a-col>
|
||
|
</a-row>
|
||
|
|
||
|
<EarthMapModal :visible="mapVisible" :enableTile="false" :enablePointer="true"
|
||
|
@closeWin="() => { mapVisible = false }" @checkPosition="checkPosition"
|
||
|
:hasMoveMethod="(subObject && subObject.id) ? true : false" @moveChinaPosition="moveChinaPosition"></EarthMapModal>
|
||
|
</div>
|
||
|
</template>
|
||
|
<script setup>
|
||
|
import { toRefs, ref, watch, computed, onMounted } from 'vue';
|
||
|
import locationPng from '@/assets/images/getLocation.png';
|
||
|
import EarthMapModal from '../MapModel/EarthMapModal.vue';
|
||
|
import { defHttp } from '@/utils/http/axios';
|
||
|
import { message } from 'ant-design-vue';
|
||
|
import { EditOutlined } from '@ant-design/icons-vue';
|
||
|
|
||
|
// 新增场景
|
||
|
const addScene = (params) => {
|
||
|
return defHttp.post({ url: "/military/msMapScene/add", params: params }, { isTransformResponse: false });
|
||
|
}
|
||
|
// 编辑场景
|
||
|
const editScene = (params) => { return defHttp.put({ url: "/military/msMapScene/edit", params: params }, { isTransformResponse: false }); }
|
||
|
// 获取场景类型字典
|
||
|
const getSceneType = () => {
|
||
|
return defHttp.get({ url: "/sys/dict/getDictItems/SceneType" }, { isTransformResponse: false });
|
||
|
}
|
||
|
// 上传图片
|
||
|
const fileUpload = (file) => {
|
||
|
return defHttp.post({ url: "/sys/common/upload", params: file }, { isTransformResponse: false });
|
||
|
}
|
||
|
// 属性
|
||
|
const props = defineProps(['subObject', "parentCodeArr", "nextNodeIndex", "parentNodeCode", "disable"]);
|
||
|
// 包装ref
|
||
|
const { parentCodeArr, nextNodeIndex, parentNodeCode, subObject, disable } = toRefs(props);
|
||
|
const emit = defineEmits(['closeWin', 'updateDataSource']);
|
||
|
const sceneTypes = ref([]);
|
||
|
// 创建编码
|
||
|
const createCode = function () {
|
||
|
if (!nextNodeIndex.value) {
|
||
|
return;
|
||
|
}
|
||
|
const nextNodeIndexStr = nextNodeIndex.value.toString();
|
||
|
const nextNodeIndexLen = nextNodeIndexStr.length;
|
||
|
let currentCode = "";
|
||
|
for (let i = 0; i < 5 - nextNodeIndexLen; i++) {
|
||
|
currentCode += "0";
|
||
|
}
|
||
|
currentCode += nextNodeIndexStr;
|
||
|
let sceneCode = null;
|
||
|
if (parentNodeCode.value.length > 0) {
|
||
|
sceneCode = parentNodeCode.value + "-" + currentCode;
|
||
|
|
||
|
|
||
|
} else {
|
||
|
sceneCode = currentCode;
|
||
|
}
|
||
|
return sceneCode;
|
||
|
}
|
||
|
// 提交
|
||
|
const handleOk = function () {
|
||
|
if (!subObject.value.sceneName || subObject.value.sceneName.length <= 0) {
|
||
|
message.warn("站点名称不能为空!");
|
||
|
return;
|
||
|
}
|
||
|
let submitUrl = "";
|
||
|
if (subObject.value.id) {
|
||
|
// 更新
|
||
|
return editScene(subObject.value).then(
|
||
|
(res) => {
|
||
|
if (res.code == 200) {
|
||
|
emit('updateDataSource', true);
|
||
|
return subObject;
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
} else {
|
||
|
// 新增
|
||
|
return addScene(subObject.value).then(
|
||
|
(res) => {
|
||
|
if (res.code == 200) {
|
||
|
emit('updateDataSource', true);
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
// 挂载后获取场景类型
|
||
|
onMounted(
|
||
|
async () => {
|
||
|
sceneTypes.value = await getSceneType().then(
|
||
|
(response) => {
|
||
|
if (response.success) {
|
||
|
return response.result;
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
)
|
||
|
// 打开地图时飞入到指定位置
|
||
|
const moveChinaPosition = function () {
|
||
|
window.earth.camera.fov = subObject.value.viewDistance;
|
||
|
window.earth.camera.position = [subObject.value.lon, subObject.value.lat, subObject.value.altitude];
|
||
|
window.earth.camera.rotation = [subObject.value.rotationX, subObject.value.rotationY, subObject.value.rotationZ]
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// const stop = watch(
|
||
|
// visible, (value, oldValue) => {
|
||
|
// if (value) {
|
||
|
// initMap()
|
||
|
// stop();
|
||
|
// }
|
||
|
// }
|
||
|
// )
|
||
|
|
||
|
// 弹窗地图框属性
|
||
|
const mapVisible = ref(false);
|
||
|
const mapShow = function () {
|
||
|
mapVisible.value = true;
|
||
|
}
|
||
|
// 关闭地图时设置,视角位置,视距信息
|
||
|
const checkPosition = function (position, cameraPosition, rotation, fov) {
|
||
|
subObject.value.lon = position[0];
|
||
|
subObject.value.lat = position[1];
|
||
|
subObject.value.altitude = position[2];
|
||
|
|
||
|
subObject.value.cameraLon = cameraPosition[0];
|
||
|
subObject.value.cameraLat = cameraPosition[1];
|
||
|
subObject.value.cameraAltitude = cameraPosition[2];
|
||
|
|
||
|
subObject.value.rotationX = rotation[0];
|
||
|
subObject.value.rotationY = rotation[1];
|
||
|
subObject.value.rotationZ = rotation[2];
|
||
|
|
||
|
subObject.value.viewDistance = fov;
|
||
|
}
|
||
|
// 图片预览的计算属性
|
||
|
const preViewUrl = computed(
|
||
|
{
|
||
|
get: () => {
|
||
|
return subObject.value.icon;
|
||
|
},
|
||
|
set: (value) => {
|
||
|
if (value) {
|
||
|
if (value.indexOf("/dt/sys/common/static/") > -1) {
|
||
|
subObject.value.icon = value;
|
||
|
} else {
|
||
|
subObject.value.icon = '/dt/sys/common/static/' + value;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
subObject.value.icon = null;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
// 上传图片
|
||
|
const preViewOk = function (fileInfo) {
|
||
|
const file = fileInfo.file
|
||
|
let formData = new FormData()
|
||
|
formData.append('file', file)
|
||
|
formData.append('biz', 'models/preView')
|
||
|
const requestCallBack = response => {
|
||
|
if (!response.success) {
|
||
|
return
|
||
|
}
|
||
|
const msg = response.message
|
||
|
if ('上传失败!' == msg) {
|
||
|
message.error('上传失败!')
|
||
|
preViewUrl.value = null;
|
||
|
} else {
|
||
|
preViewUrl.value = msg
|
||
|
message.info("上传成功!");
|
||
|
}
|
||
|
}
|
||
|
fileUpload(formData).then(requestCallBack).catch(
|
||
|
() => {
|
||
|
message.error('上传失败!')
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
// 上传图片的检查类型
|
||
|
const previewType = ref([".jpg", ".png", ".icon"]);
|
||
|
// 上传之前检查类型
|
||
|
const preBeforeUpload = function (file) {
|
||
|
const fileName = file.name
|
||
|
const fileType = fileName.substring(fileName.lastIndexOf('.'), fileName.length).toLowerCase()
|
||
|
let isFileType = false
|
||
|
for (let type of previewType.value) {
|
||
|
if (type == fileType) {
|
||
|
isFileType = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if (!isFileType) {
|
||
|
message.error('上传文件类型异常')
|
||
|
}
|
||
|
return isFileType
|
||
|
}
|
||
|
// 向父元素抛出的方法和属性
|
||
|
defineExpose({
|
||
|
preViewUrl,
|
||
|
handleOk,
|
||
|
createCode,
|
||
|
});
|
||
|
</script>
|
||
|
<style scoped>
|
||
|
.inputWidthCss1 {
|
||
|
width: 90%;
|
||
|
}
|
||
|
|
||
|
.centerText {
|
||
|
width: 100%;
|
||
|
font-weight: bold;
|
||
|
line-height: 1.8rem;
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
|
||
|
.dwImg {
|
||
|
width: 10%;
|
||
|
height: 10%;
|
||
|
margin-left: 3%;
|
||
|
cursor: pointer !important;
|
||
|
}
|
||
|
|
||
|
:deep(.ant-select) {
|
||
|
width: 90%;
|
||
|
}
|
||
|
</style>
|