徐景良 1 month ago
commit 9bb53295d4

@ -133,32 +133,26 @@ export const usePermissionStore = defineStore({
const normalizeMenu = (data) => {
let path = '';
if (data.item.url.indexOf('@') > 0) {
path = data.item.url.replace('@', '/');
if (data.url.indexOf('@') > 0) {
path = data.url.replace('@', '/');
} else {
path =
data.item.url ||
'/formCallPage?id=' +
data.item.id +
'&name=' +
data.item.name +
'&code=' +
data.item.code;
data.url || '/formCallPage?id=' + data.id + '&name=' + data.name + '&code=' + data.code;
}
const newPath = {
orderNo: data.item.sortNo,
icon: data.item.iconName,
title: data.item.name,
orderNo: data.sortNo,
icon: data.iconName,
title: data.name,
meta: {
orderNo: data.item.sortNo,
icon: data.item.iconName,
title: data.item.name,
elements: (data.item && data.item.elements) || '',
orderNo: data.sortNo,
icon: data.iconName,
title: data.name,
elements: (data && data.elements) || '',
},
name: data.item.name,
hideMenu: data.item.status == 1 ? false : true,
name: data.name,
hideMenu: data.status == 1 ? false : true,
path: path,
id: data.item.id || '',
id: data.id || '',
children: [],
};
if (data.children && data.children.length > 0) {
@ -172,56 +166,56 @@ export const usePermissionStore = defineStore({
const modules = import.meta.glob('../../views/**/**/**/index.vue');
childData.forEach((element) => {
// 菜单里配置带参数,但没有单独的主路由,先注册主路由
if (element.item.status == 1 && element.item.url.indexOf('@') > 0) {
if (router.hasRoute(element.item.code)) {
const path = element.item.url.substring(0, element.item.url.indexOf('@'));
router.addRoute(element.item.code, {
if (element.status == 1 && element.url.indexOf('@') > 0) {
if (router.hasRoute(element.code)) {
const path = element.url.substring(0, element.url.indexOf('@'));
router.addRoute(element.code, {
path: path + '/:id',
name: element.item.url.replaceAll('/', ''),
name: element.url.replaceAll('/', ''),
meta: {
title: element.item.name,
icon: element.item.iconName,
elements: element.item.elements,
title: element.name,
icon: element.iconName,
elements: element.elements,
},
component: modules['../../views/demo' + path + '/index.vue'],
});
} else {
const path = element.item.url.substring(0, element.item.url.indexOf('@'));
const path = element.url.substring(0, element.url.indexOf('@'));
router.addRoute('Root', {
path: path,
name: element.item.code,
name: element.code,
meta: {
title: element.item.name,
icon: element.item.iconName,
title: element.name,
icon: element.iconName,
hideChildrenInMenu: true,
elements: element.item.elements,
elements: element.elements,
},
component: LAYOUT,
children: [
{
path: path + '/:id',
name: element.item.url.replaceAll('/', ''),
name: element.url.replaceAll('/', ''),
meta: {
title: element.item.name,
icon: element.item.iconName,
elements: element.item.elements,
title: element.name,
icon: element.iconName,
elements: element.elements,
},
component: modules['../../views/demo' + path + '/index.vue'],
},
],
});
}
} else if (element.item.code && element.item.status == 1) {
router.addRoute(element.item.code, {
path: element.item.url,
name: element.item.url.replaceAll('/', ''),
} else if (element.code && element.status == 1) {
router.addRoute(element.code, {
path: element.url,
name: element.url.replaceAll('/', ''),
meta: {
title: element.item.name,
icon: element.item.iconName,
elements: element.item.elements,
title: element.name,
icon: element.iconName,
elements: element.elements,
},
// component: () => import('../../views/demo' + element.item.url + '/index.vue')
component: modules['../../views/demo' + element.item.url + '/index.vue'],
// component: () => import('../../views/demo' + element.url + '/index.vue')
component: modules['../../views/demo' + element.url + '/index.vue'],
});
}
if (element.children && element.children.length > 0) {
@ -232,43 +226,43 @@ export const usePermissionStore = defineStore({
// 注册路由
const registeredRoute = (data) => {
const modules = import.meta.glob('../../views/**/**/**/index.vue');
if (data.item.url.split('/')[1] == 'map') {
if (data.url.split('/')[1] == 'map') {
// 大屏的情况下不继承layout
router.addRoute('Root', {
path: data.item.url,
name: data.item.code,
path: data.url,
name: data.code,
meta: {
title: data.item.name,
icon: data.item.iconName,
elements: data.item.elements,
title: data.name,
icon: data.iconName,
elements: data.elements,
},
component: modules['../../views' + data.item.url + '/index.vue'],
component: modules['../../views' + data.url + '/index.vue'],
});
} else {
// 正常菜单
if (data.children.length == 0 && data.item.status == 1) {
if (data.children.length == 0 && data.status == 1) {
// 没有子菜单
if (data.item.url.indexOf('@') > 0) {
if (data.url.indexOf('@') > 0) {
//给带参数的路由先注册主路由
const path = data.item.url.substring(0, data.item.url.indexOf('@'));
const path = data.url.substring(0, data.url.indexOf('@'));
router.addRoute('Root', {
path: path,
name: data.item.code,
name: data.code,
meta: {
title: data.item.name,
icon: data.item.iconName,
title: data.name,
icon: data.iconName,
hideChildrenInMenu: true,
elements: data.item.elements,
elements: data.elements,
},
component: LAYOUT,
children: [
{
path: path + '/:id',
name: data.item.url.replaceAll('/', ''),
name: data.url.replaceAll('/', ''),
meta: {
title: data.item.name,
icon: data.item.iconName,
elements: data.item.elements,
title: data.name,
icon: data.iconName,
elements: data.elements,
},
component: modules['../../views/demo' + path + '/index.vue'],
},
@ -276,46 +270,44 @@ export const usePermissionStore = defineStore({
});
} else {
router.addRoute('Root', {
path: data.item.url,
name: data.item.code,
path: data.url,
name: data.code,
meta: {
title: data.item.name,
icon: data.item.iconName,
title: data.name,
icon: data.iconName,
hideChildrenInMenu: true,
elements: data.item.elements,
elements: data.elements,
},
component: LAYOUT,
children: [
{
path: data.item.url,
name: data.item.url.replaceAll('/', ''),
path: data.url,
name: data.url.replaceAll('/', ''),
meta: {
title: data.item.name,
icon: data.item.iconName,
elements: data.item.elements,
title: data.name,
icon: data.iconName,
elements: data.elements,
},
component: modules['../../views/demo' + data.item.url + '/index.vue'],
component: modules['../../views/demo' + data.url + '/index.vue'],
},
],
});
}
} else {
// 有子菜单
if (data.item.status == 0) {
if (data.status == 0) {
return;
}
router.addRoute('Root', {
path: data.item.url,
name: data.item.code,
path: data.url,
name: data.code,
meta: {
title: data.item.name,
icon: data.item.iconName,
elements: data.item.elements,
title: data.name,
icon: data.iconName,
elements: data.elements,
},
component:
data.item.parentId == 0
? LAYOUT
: modules['../../views/demo' + data.item.url + '/index.vue'],
data.parentId == 0 ? LAYOUT : modules['../../views/demo' + data.url + '/index.vue'],
});
if (data.children && data.children.length > 0) {
childRoute(data.children);

@ -1,16 +1,12 @@
<template>
<div class="pathModal">
<!-- 左侧目录 -->
<div
class="leftMenuDiv"
:style="{
width: leftMenuShow ? '340px' : '64px',
}"
>
<div class="leftMenuDiv">
<PathLeftMenu
ref="pathLeftMenuRef"
:leftMenuShow="leftMenuShow"
:allAreaDataList="allAreaDataList"
:allWorkspaceDataList="allWorkspaceDataList"
:nowShowAreaData="nowShowAreaData"
@changeLeftMenuShow="changeLeftMenuShow"
@handlerLocation="handlerLocation"
@ -28,7 +24,7 @@
<div class="mapDiv" :style="{ width: dynamicWidth }">
<PathMap
ref="pathMapRef"
:allAnnotationDataList="allAnnotationDataList"
:allWorkspaceDataList="allWorkspaceDataList"
:nowShowAnnotationData="nowShowAnnotationData"
:allAreaDataList="allAreaDataList"
:nowShowAreaData="nowShowAreaData"
@ -61,7 +57,7 @@
import { cloneDeep } from 'lodash-es';
import imageJson from './json/image.json';
import {
GetAnnotationList,
GetWorkspaceList,
DeleteAnnotation,
GetWorkAreaList,
DeleteWorkArea,
@ -71,6 +67,7 @@
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['pathRecord']);
const allWorkspaceDataList: any = ref([]);
//
const dynamicWidth = computed(() => {
let width = 0;
@ -84,7 +81,7 @@
if (areaInfoShow.value) {
width += 320;
}
return 'calc(100% - ' + width + 'px)';
return '100%';
});
// ref
@ -100,6 +97,11 @@
function changeAnnotationInfoShow() {
}
function getWorksListData() {
GetWorkspaceList().then((result1) => {
allWorkspaceDataList.value = result1;
})
}
//
function closePathAnnotationInfo() {
@ -108,7 +110,6 @@
}
//
const nowShowAnnotationData = ref();
const allAnnotationDataList: any = ref([]);
//
function setNowShowAnnotationData(value, restore = true) {
@ -120,28 +121,7 @@
//
function setAllAnnotationData() {
//
getAnnotationList();
}
//
async function getAnnotationList(showThis = true) {
allAnnotationDataList.value = await GetAnnotationList({ workspaceid: 1 });
if (allAnnotationDataList.value.length > 0) {
allAnnotationDataList.value.forEach((annotation, index) => {
let geomjson = WktToGeojson(annotation.geom);
annotation = {
...annotation,
properties: JSON.parse(annotation.properties),
geomtype: getGeomType(annotation),
coordinates: geomjson.coordinates,
};
allAnnotationDataList.value[index] = annotation;
});
}
if (showThis) {
setTimeout(() => {
pathLeftMenuRef.value.updateShowMenuInfoList('地图标注');
}, 50);
}
}
//
@ -154,7 +134,6 @@
}).then((result) => {
if (result) {
//
getAnnotationList();
createMessage.success('删除成功');
}
});
@ -193,7 +172,7 @@
}
//
async function getWorkAreaList(showThis = true) {
allAreaDataList.value = await GetWorkAreaList({ workspaceid: 1 });
allAreaDataList.value = await GetWorkAreaList();
if (allAreaDataList.value.length > 0) {
allAreaDataList.value.forEach((area, index) => {
let geomjson = WktToGeojson(area.geom);
@ -253,31 +232,30 @@
}
// WKT
function getGeomType(area) {
let geom = area.geom;
let radiusFlag = area.properties.indexOf('radius') > -1 ? true : false;
//
if (geom.indexOf('POINT') > -1 && !radiusFlag) {
return 'Point';
}
// 线
if (geom.indexOf('LINESTRING') > -1 && !radiusFlag) {
return 'Polyline';
}
//
if (geom.indexOf('POLYGON') > -1 && !radiusFlag) {
return 'Polygon';
}
//
if (geom.indexOf('POLYGON') > -1 && radiusFlag) {
return 'Circle';
}
function getGeomType(area) {
let geom = area.geom;
let radiusFlag = area.properties.indexOf('radius') > -1 ? true : false;
//
if (geom.indexOf('POINT') > -1 && !radiusFlag) {
return 'Point';
}
// 线
if (geom.indexOf('LINESTRING') > -1 && !radiusFlag) {
return 'Polyline';
}
//
if (geom.indexOf('POLYGON') > -1 && !radiusFlag) {
return 'Polygon';
}
//
if (geom.indexOf('POINT') > -1 && radiusFlag) {
return 'Circle';
}
}
onMounted(() => {
//
getWorksListData();
getWorkAreaList(false);
getAnnotationList();
});
</script>
<style lang="less" scoped>
@ -285,11 +263,16 @@
position: relative;
display: flex;
width: 100%;
height: 100vh;
height: 100%;
.leftMenuDiv {
position: relative;
height: 100%;
position:absolute;
top:20px;
left:20px;
z-index:1;
display:flex;
gap:15px;
width: 340px;
}
.mapDiv {

@ -79,14 +79,14 @@
<div class="annotationTitle">水平周长</div>
</a-col>
<a-col :span="18">
<div class="annotationContent"> {{ length.toFixed(2) }}m</div>
<div class="annotationContent"> {{ length.toFixed(2) || length }}m</div>
</a-col>
<!-- 水平面积 -->
<a-col :span="6">
<div class="annotationTitle">水平面积</div>
</a-col>
<a-col :span="18">
<div class="annotationContent"> {{ area.toFixed(2) }}</div>
<div class="annotationContent"> {{ area.toFixed(2) || area }}</div>
</a-col>
<!-- 半径 -->
<a-col :span="6" v-if="props.nowShowAreaData.geomtype == 'Circle'">

@ -7,10 +7,10 @@
</div>
<div class="leftMenuContent_list">
<!-- 地图作业区域 -->
<div v-if="showMenuInfoName == '地图作业区域'" style="margin: 10px">
<div v-if="showMenuInfoName == '地图作业区域'" style="margin: 10px 10px 20px 16px">
<a-select
v-model:value="areatype"
style="width: 120px; margin-right: 15px"
style="width: 120px; margin-right: 15px;background: #151823;"
@change="handleChangeAreaSelect"
>
<a-select-option value="all">全部类型</a-select-option>
@ -38,7 +38,6 @@
props.nowShowAreaData && props.nowShowAreaData.id == show.id
? '2px solid #2D8CF0'
: '',
background: props.nowShowAreaData && show.state == 0 ? '#3c3c3c' : '#3c3c3c55',
}"
>
<a-tooltip placement="right">
@ -52,6 +51,8 @@
>
{{ show.name }}
</div>
<div class="line"></div>
<div class="work">所属项目{{show.workSpaceName}}</div>
</a-tooltip>
<div
class="type"
@ -159,14 +160,14 @@
</div>
</div>
<div class="suojinButton" @click="changeLeftMenuShow">
<!-- <div class="suojinButton" @click="changeLeftMenuShow">
<DoubleLeftOutlined v-if="leftMenuShow" style="font-size: 16px" />
<DoubleRightOutlined v-if="!leftMenuShow" style="font-size: 16px" />
</div>
</div> -->
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { ref, watch, onMounted } from 'vue';
import {
CloseOutlined,
AntDesignOutlined,
@ -192,6 +193,7 @@
const props = defineProps([
'leftMenuShow',
'allWorkspaceDataList',
'allAreaDataList',
'nowShowAreaData',
]);
@ -204,6 +206,12 @@
]);
const showMenuInfoList = ref(props.allAreaDataList);
const showMenuInfoName = ref('地图作业区域');
onMounted(() => {
//
setTimeout(() =>{
handleChangeAreaSelect();
},1000)
});
function updateShowMenuInfoList(type) {
handleChangeAreaSelect();
}
@ -242,6 +250,13 @@
if (areastate.value !== 'all') {
filterAreaData = filterAreaData.filter((item) => item.state == areastate.value);
}
filterAreaData.forEach((annotation) => {
props.allWorkspaceDataList.forEach((tree) => {
if (tree.Id == annotation.workSpaceId) {
annotation.workSpaceName = tree.WorkspaceName
}
});
});
filterAfterAreaDataList.value = filterAreaData;
showMenuInfoList.value = filterAfterAreaDataList.value;
}
@ -287,41 +302,6 @@
// ------------------------------------------------------------------
//
function handlerLocation(position) {
// if (showMenuInfoName.value == '') {
// let coordinates = position.coordinates;
// switch (position.type) {
// case 0:
// emits('handlerLocation', {
// lng: coordinates[0],
// lat: coordinates[1],
// });
// break;
// case 1:
// emits('handlerLocation', {
// lng: coordinates[0][0],
// lat: coordinates[0][1],
// });
// break;
// case 2:
// emits('handlerLocation', {
// lng: coordinates[0][0][0],
// lat: coordinates[0][0][1],
// });
// break;
// case 3:
// emits('handlerLocation', {
// lng: coordinates[0],
// lat: coordinates[1],
// });
// break;
// }
// }
// if (showMenuInfoName.value == '') {
// emits('handlerLocation', {
// lng: position.photo_position.lng,
// lat: position.photo_position.lat,
// });
// }
if (showMenuInfoName.value == '地图作业区域') {
if (position.geomtype == 'Circle') {
emits('handlerLocation', {
@ -343,10 +323,12 @@
</script>
<style lang="less" scoped>
.leftMenu {
position: relative;
width: 100%;
height: 100%;
background: #232323;
width:100%;
height:100%;
background: #0D0E15;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15), 0px 10px 30px 1px rgba(0,0,6,0.15), inset 0px 0px 20px 8px rgba(58,87,232,0.73);
border-radius: 6px;
position:relative;
.leftMenuTitle {
position: relative;
@ -441,19 +423,19 @@
.leftMenuContent_2 {
position: relative;
width: 275px;
width: 100%;
height: 100%;
.leftMenuContent_title {
margin-top: 10px;
margin-left: 10px;
color: #ffffff;
font-size: 16px;
padding:15px 15px;
color:#fff;
border-bottom:1px solid rgba(255,255,255,0.15);
}
.leftMenuContent_list {
overflow-y: auto;
max-height: 800px;
max-height: 720px;
//
.showMenuInfo_annotation {
@ -524,31 +506,49 @@
display: flex;
align-items: center;
justify-content: flex-start;
height: 70px;
height: 100px;
margin: 10px 15px;
background: #313C62;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
border-radius: 6px;
.name {
position: absolute;
top: 6px;
left: 6px;
top: 2px;
left: 16px;
color: #ffffff;
font-size: 15px;
font-size: 14px;
width: 90%;
height: 30px;
height: 34px;
line-height: 34px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.work{
position: absolute;
top: 33px;
left: 16px;
color: #ffffff;
font-size: 13px;
}
.line{
width: 310px;
height: 1px;
box-shadow: 0px 10px 30px 0px rgba(0,0,6,0.15);
border: 1px solid;
opacity: 0.2;
border-image: linear-gradient(270deg, rgba(96, 107, 146, 0), rgba(154, 164, 196, 1)) 1 1;
margin-top: 12px;
}
.type {
position: absolute;
display: inline-flex;
align-items: center;
justify-content: flex-start;
bottom: 6px;
left: 8px;
bottom: 13px;
left: 16px;
color: #ffffff;
font-size: 15px;
font-size: 12px;
width: 165px;
}
.buttonlist {

@ -1,9 +1,9 @@
<template>
<div ref="vChartRef" id="mars3d-container" class="mars3d-container">
<div class="annotationButtons">
<!-- <div class="annotationButtons">
<div
:class="mapDrawType == 'drawPoint' ? 'button_choose' : 'button_nochoose'"
@click="drawPoint"
@click="fun_chooseWorkSpaceType('drawPoint')"
>
<a-popover placement="left">
<template #content>
@ -29,7 +29,7 @@
</div>
<div
:class="mapDrawType == 'drawPolyline' ? 'button_choose' : 'button_nochoose'"
@click="drawPolyline"
@click="fun_chooseWorkSpaceType('drawPolyline')"
>
<a-popover placement="left">
<template #content>
@ -55,7 +55,7 @@
</div>
<div
:class="mapDrawType == 'drawPolygon' ? 'button_choose' : 'button_nochoose'"
@click="drawPolygon"
@click="fun_chooseWorkSpaceType('drawPolygon')"
>
<a-popover placement="left">
<template #content>
@ -81,7 +81,7 @@
</div>
<div
:class="mapDrawType == 'drawCricle' ? 'button_choose' : 'button_nochoose'"
@click="drawCricle"
@click="fun_chooseWorkSpaceType('drawCricle')"
>
<a-popover placement="left">
<template #content>
@ -105,12 +105,12 @@
/>
</a-popover>
</div>
</div>
</div> -->
<div class="areaButtons">
<div
:class="mapAreaDrawFlag ? 'button_choose' : 'button_nochoose'"
style="border-radius: 3px"
@click="drawArea"
@click="fun_chooseWorkSpaceType('drawArea')"
>
<a-popover placement="leftTop">
<template #content>
@ -205,6 +205,34 @@
</div>
</div>
</div>
<a-modal
title="选择项目"
:open="chooseWorkSpaceOpen"
:mask="false"
:maskClosable="false"
:closable="false"
@ok="fun_workSpaceOk"
@cancel="fun_workSpaceCancel"
>
<div style="margin: 10px 30px">
<a-radio-group v-model:value="chooseWorkSpaceId">
<a-radio
v-for="workspace in props.allWorkspaceDataList"
style="
display: flex;
align-items: center;
justify-content: flex-start;
height: 30px;
lineheight: 30px;
"
:key="workspace.Id"
:value="workspace.Id"
>
{{ workspace.WorkspaceName }}
</a-radio>
</a-radio-group>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { ref, watch, onMounted, defineEmits } from 'vue';
@ -227,9 +255,11 @@
import * as turf from '@turf/turf';
import { WktToGeojson, GeojsonToWkt } from '@/components/MapboxMaps/src/WktGeojsonTransform';
import dayjs from 'dayjs';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
const props = defineProps([
'allAnnotationDataList',
'allWorkspaceDataList',
'nowShowAnnotationData',
'allImageDataList',
'nowShowImageData',
@ -251,6 +281,7 @@
let graphicLayers = new mars3d.layer.GraphicLayer({
isAutoEditing: true,
});
//
// -
let annotation_PointGraphicData: any = [];
@ -633,6 +664,7 @@
deep: true,
},
);
// --
const showAllAnnotationDataList = async () => {
//
@ -960,13 +992,52 @@
const drawColorPolygon = ref('#2D8CF0');
const drawColorCricle = ref('#2D8CF0');
// --
async function drawPoint() {
if (mapDrawType.value == 'drawPoint') {
mapDrawType.value = '';
//
const chooseWorkSpaceOpen = ref(false);
const chooseWorkSpaceId = ref('');
//
function fun_chooseWorkSpaceType(type) {
chooseWorkSpaceOpen.value = true;
mapDrawType.value = type;
}
// -
function fun_workSpaceOk() {
if (chooseWorkSpaceId.value == '') {
createMessage.warning('先选择要标注的项目!');
return;
}
mapDrawType.value = 'drawPoint';
chooseWorkSpaceOpen.value = false;
switch (mapDrawType.value) {
// --
case 'drawPoint':
drawPoint();
break;
// --线
case 'drawPolyline':
drawPolyline();
break;
// --
case 'drawPolygon':
drawPolygon();
break;
// --
case 'drawCricle':
drawCricle();
break;
case 'drawArea':
drawArea();
break;
}
}
//
function fun_workSpaceCancel() {
chooseWorkSpaceOpen.value = false;
mapDrawType.value = '';
chooseWorkSpaceId.value == '';
}
// --
async function drawPoint() {
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
const graphic = await graphicLayers.startDraw({
type: 'billboard',
@ -990,11 +1061,6 @@
}
// --线
async function drawPolyline() {
if (mapDrawType.value == 'drawPolyline') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawPolyline';
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
const graphic = await graphicLayers.startDraw({
type: 'polyline',
@ -1021,11 +1087,6 @@
}
// --
async function drawPolygon() {
if (mapDrawType.value == 'drawPolygon') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawPolygon';
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
const graphic = await graphicLayers.startDraw({
type: 'polygon',
@ -1050,11 +1111,6 @@
}
// --
async function drawCricle() {
if (mapDrawType.value == 'drawCricle') {
mapDrawType.value = '';
return;
}
mapDrawType.value = 'drawCricle';
let time = dayjs().format('YYYY-MM-DD HH:mm:ss');
const graphic = await graphicLayers.startDraw({
type: 'circle',
@ -1131,7 +1187,7 @@
break;
case 'circle':
type = 3;
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
geom = GeojsonToWkt(turf.point(coordinates, graphicJson.style.radius).geometry);
properties = {
font_size: 16,
clampToGround: true,
@ -1149,7 +1205,7 @@
createTime: time,
createUser: '',
geom: geom,
workSpaceId: '1',
workSpaceId: chooseWorkSpaceId.value,
state: 0,
createUserName: '',
};
@ -1157,6 +1213,7 @@
//
emits('setAllAnnotationData');
mapDrawType.value = '';
});
} else {
params = {
@ -1165,7 +1222,7 @@
type: type,
properties: JSON.stringify(properties),
geom: geom,
workSpaceId: '1',
workSpaceId: chooseWorkSpaceId.value,
state: props.nowShowAnnotationData.state,
};
UpdateAnnotation(params).then((result) => {
@ -1576,7 +1633,7 @@
watch(
() => area_noland_PolygonGraphicData,
() => {
console.log(area_noland_PolygonGraphicData);
},
{
deep: true,
@ -2263,7 +2320,7 @@
//
case 'dfence_Circle':
type = 'dfence';
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
geom = GeojsonToWkt(turf.point(coordinates, graphicJson.style.radius).geometry);
properties = {
clampToGround: true,
color: '#00FF00',
@ -2274,7 +2331,7 @@
//
case 'nfz_Circle':
type = 'nfz';
geom = GeojsonToWkt(turf.circle(coordinates, graphicJson.style.radius).geometry);
geom = GeojsonToWkt(turf.point(coordinates, graphicJson.style.radius).geometry);
properties = {
clampToGround: true,
color: '#FF0000',
@ -2291,7 +2348,7 @@
createTime: time,
createUser: '',
geom: geom,
workSpaceId: '1',
workSpaceId: chooseWorkSpaceId.value,
state: 0,
createUserName: '',
};
@ -2307,7 +2364,7 @@
type: type,
properties: JSON.stringify(properties),
geom: geom,
workSpaceId: '1',
workSpaceId: chooseWorkSpaceId.value,
state: props.nowShowAreaData.state,
};
UpdateWorkArea(params).then((result) => {
@ -2323,6 +2380,7 @@
const position = Cesium.Cartesian3.fromDegrees(lngLat[0], lngLat[1]);
map.flyToPoint(position);
};
defineExpose({
setNowShowImageByRight,
@ -2393,7 +2451,7 @@
display: flex;
align-items: center;
justify-content: center;
top: 30%;
top: 15%;
right: 1%;
width: 30px;
height: 30px;

@ -1,7 +1,9 @@
<template>
<BasicTable @register="registerTable">
<template #toolbar>
<!-- <a-button type="primary" @click=""></a-button> -->
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<a-button v-if="!record.tasklist" type="primary" @click="openDraw(record)"></a-button>
</template>
</template>
</BasicTable>
</template>
@ -11,6 +13,9 @@ import { ref, defineProps, onMounted, watch, nextTick } from "vue"
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { columns, searchFormSchema } from './utils'
import { GetDataList } from '@/api/demo/provincetasks'
import { useRouter } from 'vue-router'
const router = useRouter()
const [registerTable, { reload, expandAll, getForm,getDataSource,setTableData }] = useTable({
title: '任务列表',
@ -29,6 +34,11 @@ const [registerTable, { reload, expandAll, getForm,getDataSource,setTableData }]
//
showTableSetting: true,
bordered: false,
actionColumn: {
width: 160,
title: '操作',
dataIndex: 'action',
},
beforeFetch(data) {
return data
},
@ -41,6 +51,14 @@ const [registerTable, { reload, expandAll, getForm,getDataSource,setTableData }]
return info;
},
});
const openDraw = (e) =>{
router.push({
path: '/workmanagement/workplan',
query: {
taskid: e.id
}
})
}
</script>
<style lang="scss" scoped>

@ -1,7 +1,7 @@
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<LeftTree ref="childRef" class="w-1/5 xl:w-1/6" @select="handleSelect" />
<div class="w-4/5 xl:w-5/6">
<LeftTree v-if="!pathDivShow" ref="childRef" class="w-1/5 xl:w-1/6" @select="handleSelect" />
<div v-if="!pathDivShow" class="w-4/5 xl:w-5/6">
<BasicTable @register="registerTable" :searchInfo="searchInfo">
<template #toolbar>
<span v-for="(f, index) in floders" :key="f.id" class="floderTitle">
@ -30,33 +30,55 @@
</div>
</template>
<template #bodyCell="{ column, record }">
<div v-if="tableType == 'table'">
<div v-if="tableTypeAfterShow == 'table'">
<template v-if="column.key === 'name'">
<!-- 文件夹 -->
<FolderOpenOutlined v-if="!record.objectKey" style="font-size: 20px" />
<FileOutlined
v-if="record.objectKey && !record.objectKey.includes('jpeg')"
style="font-size: 20px"
/>
<!-- 图片 -->
<img
v-if="record.objectKey && record.objectKey.includes('jpeg')"
:src="getImgurl(record.objectKey)"
:src="`${VITE_MEDIALIBRARY_IMAGE_URL + (record.minipic ? record.minipic : record.objectKey)}`"
:width="30"
:height="20"
/>
<!-- 视频 -->
<PlaySquareTwoTone
v-if="record.objectKey && record.objectKey.includes('mp4')"
style="font-size: 20px"
/>
<!-- 文件夹或者图片视频 -->
<span
v-if="!record.objectKey || (record.objectKey && record.objectKey.includes('jpeg'))"
v-if="
!record.objectKey ||
(record.objectKey &&
(record.objectKey.includes('jpeg') || record.objectKey.includes('mp4')))
"
@click="lookRecord(record)"
@mouseover="record.isHovered = true"
@mouseout="record.isHovered = false"
:style="{
textDecoration: record.isHovered ? 'underline' : 'none',
cursor: record.isHovered ? 'pointer' : 'default',
marginLeft: '5px',
}"
>
{{ record.name }}
</span>
<!-- 其他文件 -->
<FileOutlined
v-if="
record.objectKey &&
!record.objectKey.includes('jpeg') &&
!record.objectKey.includes('mp4')
"
style="font-size: 20px"
/>
<span
v-if="record.objectKey && !record.objectKey.includes('jpeg')"
v-if="
record.objectKey &&
!record.objectKey.includes('jpeg') &&
!record.objectKey.includes('mp4')
"
:style="{
marginLeft: '5px',
}"
@ -93,17 +115,6 @@
<EditOutlined @click="renameRecord(record)" />
</a-button>
</a-tooltip>
<a-tooltip placement="top">
<template #title>
<span>查看地图图片历史路径</span>
</template>
<a-button
type="text"
v-if="record.objectKey && record.objectKey.includes('.jpeg')"
>
<BorderInnerOutlined @click="openPathModal(record)" />
</a-button>
</a-tooltip>
<a-tooltip placement="top">
<template #title>
<span>
@ -127,17 +138,33 @@
/>
</a-button>
</a-tooltip>
<a-tooltip placement="top">
<template #title>
<div>查看地图图片历史路径</div>
<div>只展示在地图上加载的图片</div>
</template>
<a-button
type="text"
v-if="
record.objectKey &&
record.objectKey.includes('.jpeg') &&
record.showOnMap == 1
"
>
<BorderInnerOutlined @click="showPathDiv(record)" />
</a-button>
</a-tooltip>
</div>
</template>
</div>
</template>
</BasicTable>
<div v-if="tableType == 'store'" class="storeDivsAllChoose">
<div v-if="tableTypeAfterShow == 'store'" class="storeDivsAllChoose">
<a-checkbox v-model:checked="checkNameChecked" @change="changeStore($event, 'allChoose')">
全选
</a-checkbox>
</div>
<div v-if="tableType == 'store'" class="storeDivs">
<div v-if="tableTypeAfterShow == 'store'" class="storeDivList">
<div
v-for="record in showTableData"
:key="record.id"
@ -146,38 +173,65 @@
@mouseover="record.isHovered = true"
@mouseout="record.isHovered = false"
>
<!-- 选中 -->
<div style="position: absolute; top: 0px; left: 5px">
<a-checkbox v-model:checked="record.checked" @change="changeStore($event, record)" />
</div>
<!-- 文件夹 -->
<FolderOpenOutlined
v-if="!record.objectKey"
style="font-size: 40px"
@click="lookRecord(record)"
/>
<!-- 图片 -->
<img
v-if="record.objectKey"
:src="getImgurl(record.objectKey)"
:width="60"
:height="40"
v-if="record.objectKey && record.objectKey.includes('jpeg')"
:src="`${VITE_MEDIALIBRARY_IMAGE_URL + (record.minipic ? record.minipic : record.objectKey)}`"
:width="100"
:height="60"
style="position: absolute; top: 10px; left: 32.5px"
@click="lookRecord(record)"
/>
<!-- 视频 -->
<PlaySquareTwoTone
v-if="record.objectKey && record.objectKey.includes('mp4')"
style="font-size: 40px"
/>
<!-- 文件夹或者图片视频 -->
<span
v-if="
!record.objectKey ||
(record.objectKey &&
(record.objectKey.includes('jpeg') || record.objectKey.includes('mp4')))
"
class="storeDivSpanName"
:style="{
textDecoration: record.isHovered ? 'underline' : 'none',
position: 'absolute',
bottom: '10px',
left: '0px',
width: '100%',
height: '30px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
cursor: record.isHovered ? 'pointer' : 'default',
}"
@click="lookRecord(record)"
>
{{ record.name }}
</span>
<!-- 其他文件 -->
<FileOutlined
v-if="
record.objectKey &&
!record.objectKey.includes('jpeg') &&
!record.objectKey.includes('mp4')
"
style="font-size: 40px"
/>
<span
v-if="
record.objectKey &&
!record.objectKey.includes('jpeg') &&
!record.objectKey.includes('mp4')
"
class="storeDivSpanName"
>
{{ record.name }}
</span>
</div>
</div>
</div>
@ -210,11 +264,12 @@
@chooseNowPreviewRecord="chooseNowPreviewRecord"
@closeModal="closeModal"
@handleSuccess="handleSuccess"
@openPathModal="openPathModal"
/>
</a-modal>
<!-- 变化检测弹窗 -->
<!-- 路径地图弹窗 -->
<a-modal
v-model:open="comparisonOpen"
v-model:open="pathOpen"
width="100%"
wrap-class-name="full-modal"
:centered="true"
@ -225,11 +280,18 @@
:mask="false"
:maskClosable="false"
>
<Comparison @closeComparisonModal="closeComparisonModal" />
<Path
:pathDivShow="pathDivShow"
:allImageDataList="allImageDataList"
:nowShowImageData="nowShowImageData"
:floderName="floderName"
@closePathModal="closePathModal"
@handleSuccessPath="handleSuccessPath"
/>
</a-modal>
<!-- 路径地图弹窗 -->
<!-- 变化检测弹窗 -->
<a-modal
v-model:open="pathOpen"
v-model:open="comparisonOpen"
width="100%"
wrap-class-name="full-modal"
:centered="true"
@ -240,14 +302,18 @@
:mask="false"
:maskClosable="false"
>
<Path
:allImageDataList="allImageDataList"
:nowShowImageData="nowShowImageData"
:floderName="floderName"
@closePathModal="closePathModal"
@handleSuccessPath="handleSuccessPath"
/>
<Comparison @closeComparisonModal="closeComparisonModal" />
</a-modal>
<Path
v-if="pathDivShow"
:pathDivShow="pathDivShow"
:allImageDataList="allImageDataList"
:nowShowImageData="nowShowImageData"
:floderName="floderName"
@closePathModal="closePathModal"
@handleSuccessPath="handleSuccessPath"
/>
</PageWrapper>
</template>
<script lang="ts" setup>
@ -271,6 +337,7 @@
PlaySquareTwoTone,
FileOutlined,
BorderInnerOutlined,
YoutubeOutlined,
} from '@ant-design/icons-vue';
import {
GetMediaFile,
@ -298,51 +365,76 @@
const showTableData = ref();
//
const tableType = ref('table');
const tableTypeAfterShow = ref('table');
const tableHeight: any = ref(0);
watch(
() => tableType.value,
(newval) => {
showTableData.value = getDataSource();
//
const containers = document.querySelectorAll('.ant-table-container');
if (newval) {
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
} else {
tableHeight.value = 0;
}
if (containers) {
containers.forEach((container) => {
container.style.display = tableType.value === 'table' ? 'block' : 'none';
});
}
//
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = tableType.value === 'table' ? 'block' : 'none';
//
if (newval === 'store') {
//
GetMediaFile({
parentKey: nowParentKey.value,
page: 1,
limit: 1000,
}).then((res) => {
showTableData.value = res.items;
tableTypeAfterShow.value = newval;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'none';
});
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'none';
});
}
//
let selectRowsIdArray = getSelectRows().map((item) => item.id);
showTableData.value.forEach((item) => {
if (selectRowsIdArray.includes(item.id)) {
item.checked = true;
changeStore(
{
target: {
checked: true,
},
},
item,
);
}
});
});
}
//
//
if (tableType.value === 'store') {
let selectRowsIdArray = getSelectRows().map((item) => item.id);
showTableData.value.forEach((item) => {
if (selectRowsIdArray.includes(item.id)) {
item.checked = true;
changeStore(
{
target: {
checked: true,
},
},
item,
);
//
if (newval === 'table') {
reload().then((res) => {
tableTypeAfterShow.value = newval;
// -
const containers = document.querySelectorAll('.ant-table-container');
tableHeight.value = containers[0] ? containers[0]?.scrollHeight : 0;
if (containers) {
containers.forEach((container) => {
container.style.display = 'block';
});
}
// -
const paginations = document.querySelectorAll('.ant-pagination');
if (paginations) {
paginations.forEach((pagination) => {
pagination.style.display = 'block';
});
}
//
let selectRowsIdArray = showTableData.value.filter((item) => item.checked);
setSelectedRows(selectRowsIdArray);
});
} else {
//
let selectRowsIdArray = showTableData.value.filter((item) => item.checked);
setSelectedRows(selectRowsIdArray);
}
},
);
@ -415,6 +507,8 @@
//
let temp = {
...data,
page: tableTypeAfterShow.value == 'table' ? data.page : 1,
limit: tableTypeAfterShow.value == 'table' ? data.limit : 1000,
parentKey: nowParentKey.value,
};
return temp;
@ -456,16 +550,6 @@
showTableData.value = res;
});
}
//
function getImgurl(url) {
let uu = VITE_MEDIALIBRARY_IMAGE_URL + url;
// 使
// getImageDimensions(uu, function (dimensions) {
// console.log(': ' + dimensions.width);
// console.log(': ' + dimensions.height);
// });
return uu;
}
function getImageDimensions(url, callback) {
const img = new Image();
@ -510,12 +594,10 @@
page: 1,
limit: 100,
}).then((res) => {
previewRecordList.value = uniqueByKey(res.items, null);
getDataSource().forEach((item) => {
if (item.id == nowPreviewRecord.value.id) {
nowPreviewRecord.value = item;
}
});
previewRecordList.value = uniqueByKey(res.items, nowPreviewRecord.value);
nowPreviewRecord.value = getDataSource().find(
(item) => item.id == nowPreviewRecord.value.id,
);
});
}
}, 500);
@ -549,16 +631,16 @@
}
//
function compressFolderOrFile() {
let rows = getSelectRows();
if (rows.length > 0) {
const record = rows;
openCompressFileModal(true, {
tableData: getDataSource(),
record,
});
} else {
return createMessage.warn('请选择一个或者多个文件/文件夹压缩');
}
// let rows = getSelectRows();
// if (rows.length > 0) {
// const record = rows;
// openCompressFileModal(true, {
// tableData: getDataSource(),
// record,
// });
// } else {
// return createMessage.warn('/');
// }
}
//
function renameRecord(record) {
@ -601,7 +683,7 @@
id: record.id,
fileTags: record.fileTags,
graffitiJson: record.graffitis,
display: record.display,
display: record.showOnMap == 1 ? 0 : 1,
showOnMap: record.showOnMap == 1 ? 0 : 1,
}).then((res) => {
if (record.showOnMap == 1) {
@ -620,16 +702,8 @@
const previewRecordList: any = ref([]);
// -
async function lookRecord(record) {
if (!record.objectKey) {
nowParentKey.value = record.id;
floders.value.push({
id: nowParentKey.value,
name: record.name,
});
reload().then((res) => {
showTableData.value = res;
});
} else {
//
if (record.objectKey) {
GetMediaFile({
...searchParams.value,
parentKey: nowParentKey.value,
@ -637,53 +711,59 @@
limit: 100,
}).then((res) => {
nowPreviewRecord.value = record;
//
previewRecordList.value = uniqueByKey(res.items, record);
open.value = true;
});
}
//
if (!record.objectKey) {
nowParentKey.value = record.id;
floders.value.push({
id: nowParentKey.value,
name: record.name,
});
reload().then((res) => {
showTableData.value = res;
});
}
}
//
function uniqueByKey(arrlist, record) {
let resultList: any = [];
arrlist.forEach((arr) => {
if (
arr.objectKey &&
!resultList.some((item) => item.objectKey === arr.objectKey) &&
arr.objectKey.includes('jpeg')
) {
//
if (record) {
if (
(arr.objectKey == record.objectKey && record.id == arr.id) ||
arr.objectKey != record.objectKey
) {
if (!arr.fileTags) {
arr.fileTags = [];
} else {
arr.fileTags = JSON.parse(arr.fileTags);
}
if (!arr.graffitiJson) {
arr.graffitiJson = [];
} else {
arr.graffitiJson = JSON.parse(arr.graffitiJson);
}
resultList.push(arr);
if (record.objectKey.includes('.jpeg')) {
arrlist
.filter((item) => item.objectKey && item.objectKey.includes('jpeg'))
.forEach((item) => {
if (!item.fileTags) {
item.fileTags = [];
} else {
item.fileTags = JSON.parse(item.fileTags);
}
} else {
if (!arr.fileTags) {
arr.fileTags = [];
if (!item.graffitiJson) {
item.graffitiJson = [];
} else {
arr.fileTags = JSON.parse(arr.fileTags);
item.graffitiJson = JSON.parse(item.graffitiJson);
}
if (!arr.graffitiJson) {
arr.graffitiJson = [];
resultList.push(item);
});
}
if (record.objectKey.includes('mp4')) {
arrlist
.filter((item) => item.objectKey && item.objectKey.includes('mp4'))
.forEach((item) => {
if (!item.fileTags) {
item.fileTags = [];
} else {
arr.graffitiJson = JSON.parse(arr.graffitiJson);
item.fileTags = JSON.parse(item.fileTags);
}
resultList.push(arr);
}
}
});
if (!item.graffitiJson) {
item.graffitiJson = [];
} else {
item.graffitiJson = JSON.parse(item.graffitiJson);
}
resultList.push(item);
});
}
return resultList;
}
//
@ -709,7 +789,7 @@
// ----------------------------------------------------------------------
const pathOpen = ref(false);
//
//
const floderName = ref('');
const nowShowImageData = ref({});
const allImageDataList: any = ref([]);
@ -734,20 +814,50 @@
arr.graffitiJson = [];
}
});
nowShowImageData.value = allImageDataList.value.filter((item) => item.id == record.id)[0];
nowShowImageData.value = allImageDataList.value.find((item) => item.id == record.id);
floderName.value = floders.value[floders.value.length - 1].name;
pathOpen.value = true;
});
}
//
//
const pathDivShow = ref(false);
function showPathDiv(record) {
GetMediaFile({
parentKey: record.parentKey,
page: 1,
limit: 1000,
}).then((res) => {
allImageDataList.value = res.items.filter(
(item) => item.objectKey && item.objectKey.includes('.jpeg'),
);
allImageDataList.value.forEach((arr) => {
if (arr.fileTags) {
arr.fileTags = JSON.parse(arr.fileTags);
} else {
arr.fileTags = [];
}
if (arr.graffitiJson) {
arr.graffitiJson = JSON.parse(arr.graffitiJson);
} else {
arr.graffitiJson = [];
}
});
nowShowImageData.value = allImageDataList.value.find((item) => item.id == record.id);
floderName.value = floders.value[floders.value.length - 1].name;
pathDivShow.value = true;
});
}
//
function closePathModal() {
nowShowImageData.value = {};
pathOpen.value = false;
pathDivShow.value = false;
}
//
function handleSuccessPath() {
function handleSuccessPath(value) {
setTimeout(() => {
openPathModal(nowShowImageData.value);
pathDivShow.value ? showPathDiv(value) : openPathModal(value);
// openPathModal(value);
reload();
}, 500);
}
@ -803,29 +913,47 @@
padding-left: 16px;
background: #ffffff;
display: flex;
align-items: flex-start;
align-items: center;
justify-content: flex-start;
}
.storeDivs {
.storeDivList {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: flex-start;
width: 100%;
height: 566px;
height: 72.5%;
background: #ffffff;
margin: 0px 16px 16px 16px;
// gap: 20px;
overflow-y: auto;
.storeDiv {
position: relative;
width: 160px;
height: 120px;
width: 165px;
height: 130px;
outline: 1px solid #000000;
margin: 16px;
display: flex;
align-items: center;
justify-content: center;
.storeDivSpanName {
position: absolute;
bottom: 16px;
left: 0px;
width: 100%;
height: 30px;
cursor: pointer;
white-space: pre-wrap;
word-break: break-all;
overflow-wrap: break-word;
max-width: 100%;
display: block;
}
}
}
@ -838,4 +966,10 @@
::v-deep .vben-basic-table {
height: fit-content !important;
}
::v-deep .full-modal {
height: 100% !important;
}
::v-deep .ant-modal-body {
height: 100% !important;
}
</style>

@ -207,8 +207,8 @@ export const svg_showOnMap_1 = `<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 24 24"
width="18"
height="18"
width="16"
height="16"
>
<path
d="M19 5v11.17l2 2V5c0-1.1-.9-2-2-2H5.83l2 2H19zM2.81 2.81L1.39 4.22L3 5.83V19c0 1.1.9 2 2 2h13.17l1.61 1.61l1.41-1.41L2.81 2.81zM5 19V7.83l7.07 7.07l-.82 1.1L9 13l-3 4h8.17l2 2H5z"
@ -220,8 +220,8 @@ export const svg_showOnMap_0 = `<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 24 24"
width="18"
height="18"
width="16"
height="16"
>
<path
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14L6 17h12l-3.86-5.14z"

@ -1,5 +1,10 @@
<template>
<div class="pathModal">
<div
class="pathModal"
:style="{
height: props.pathDivShow ? '100%' : '100vh',
}"
>
<!-- 左侧目录 -->
<div
class="leftMenuDiv"
@ -51,7 +56,7 @@
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['allImageDataList', 'nowShowImageData', 'floderName']);
const props = defineProps(['allImageDataList', 'nowShowImageData', 'floderName', 'pathDivShow']);
const emits = defineEmits(['closePathModal', 'handleSuccessPath']);
//
const dynamicWidth = computed(() => {
@ -77,7 +82,7 @@
}
// ----------------------------------------------------
const imageInfoShow = ref(false);
const imageInfoShow = ref(true);
//
const nowShowImageData = ref();
const allImageDataList = ref();
@ -130,8 +135,8 @@
pathMapRef.value.handlerLocation([position.lng, position.lat]);
}
//
function handleSuccessPath() {
emits('handleSuccessPath');
function handleSuccessPath(value) {
emits('handleSuccessPath', value);
}
</script>
<style lang="less" scoped>
@ -139,7 +144,6 @@
position: relative;
display: flex;
width: 100%;
height: 100vh;
.leftMenuDiv {
position: relative;
@ -160,4 +164,11 @@
// min-width: 720px;
}
}
::v-deep .full-modal {
height: 100% !important;
}
::v-deep .ant-modal-body {
height: 100% !important;
}
</style>

@ -95,19 +95,26 @@
<template #title>
<span>{{ hideOrShowGraffitiFlag ? '点击隐藏涂鸦信息' : '点击显示涂鸦信息' }}</span>
</template>
<EyeOutlined @click="hideOrShowGraffiti(false)" v-if="hideOrShowGraffitiFlag" />
<EyeInvisibleOutlined @click="hideOrShowGraffiti(true)" v-if="!hideOrShowGraffitiFlag" />
<div
style="
position: absolute;
bottom: 0px;
right: 0px;
font-size: 10px;
color: #000000;
pointer-events: none;
"
>
涂鸦
<EyeOutlined
@click="hideOrShowGraffiti(false)"
v-if="hideOrShowGraffitiFlag"
style="color: #2d8cf0"
/>
<EyeInvisibleOutlined
@click="hideOrShowGraffiti(true)"
v-if="!hideOrShowGraffitiFlag"
style="color: #595959"
/>
<div style="position: absolute; bottom: -12px; right: -5px; pointer-events: none">
<div
v-html="
`${
hideOrShowGraffitiFlag
? graffiti_svg.replaceAll('currentColor', '#2d8cf0')
: graffiti_svg.replaceAll('currentColor', '#595959')
}`
"
/>
</div>
</a-tooltip>
</div>
@ -178,9 +185,16 @@
<CloseOutlined
style="margin-right: 10px; color: red"
@click="
rect.text ? (rect.text = graffitisClone[index].text) : (rect.text = '');
rect.text
? ((rect.x = graffitisClone[index].x),
(rect.y = graffitisClone[index].y),
(rect.width = graffitisClone[index].width),
(rect.height = graffitisClone[index].height),
(rect.color = graffitisClone[index].color),
(rect.text = graffitisClone[index].text),
(rect.status = 'success'))
: graffitis.splice(index, 1);
nowGraffiti = -1;
rect.status = 'success';
"
/>
<DeleteOutlined
@ -218,12 +232,14 @@
:style="{
textDecoration: rect.status == 'mouse' ? 'underline' : '',
}"
@mouseenter="rect.status != 'edit' ? (rect.status = 'mouse') : ''"
@mouseleave="rect.status == 'mouse' ? (rect.status = 'success') : ''"
@mouseenter="graffitiFlag && rect.status != 'edit' ? (rect.status = 'mouse') : ''"
@mouseleave="graffitiFlag && rect.status == 'mouse' ? (rect.status = 'success') : ''"
@click="
rect.status = 'edit';
graffitisClone = cloneDeep(graffitis);
nowGraffiti = index;
graffitiFlag
? ((rect.status = 'edit'),
(graffitisClone = cloneDeep(graffitis)),
(nowGraffiti = index))
: ''
"
>
{{ rect.text }}
@ -242,10 +258,7 @@
}"
@mouseenter="mouseenter(rect, 'top')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'top')"
/>
<!-- -->
@ -261,10 +274,7 @@
}"
@mouseenter="mouseenter(rect, 'bottom')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'bottom')"
/>
<!-- -->
@ -280,10 +290,7 @@
}"
@mouseenter="mouseenter(rect, 'right')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'right')"
/>
<!-- -->
@ -299,10 +306,7 @@
}"
@mouseenter="mouseenter(rect, 'left')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'left')"
/>
<!-- 左上 -->
@ -490,19 +494,30 @@
</div>
</div>
<div class="imageChooseList">
<div v-for="li in props.allImageDataList" :key="li.id" @click="setNowShowImageData(li)">
<div :class="li.id == props.nowShowImageData.id ? 'bottom_div_choose' : 'bottom_div'">
<img
v-if="li.display == 1 && li.showOnMap == 1"
:src="
li.preview_url
? li.preview_url
: 'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871'
"
width="75"
height="50"
/>
</div>
<div
v-for="li in props.allImageDataList.filter(
(item) => item.display == 1 && item.showOnMap == 1,
)"
:key="li.id"
@click="setNowShowImageData(li)"
>
<a-tooltip placement="top">
<template #title>
<span>{{ li.name }}</span>
</template>
<div :class="li.id == props.nowShowImageData.id ? 'bottom_div_choose' : 'bottom_div'">
<img
:src="
li.minipic
? VITE_MEDIALIBRARY_IMAGE_URL + li.minipic
: 'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871'
"
loading="lazy"
width="75"
height="50"
/>
</div>
</a-tooltip>
</div>
</div>
</div>
@ -585,6 +600,7 @@
} from '@ant-design/icons-vue';
import dayjs from 'dayjs';
import { UpdatePicStatus, UpdatePicName } from '@/api/demo/mediaLibrary';
import { graffiti_svg } from './svg';
import { getAppEnvConfig } from '@/utils/env';
import { cloneDeep } from 'lodash-es';
import { useMessage } from '@/hooks/web/useMessage';
@ -632,7 +648,7 @@
editNameFlag.value = true;
createMessage.success(res);
emits('funUpdateDisplayOrShowOnMapData', props.nowShowImageData);
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
}
function editNameBlur() {
@ -684,10 +700,10 @@
// ----------------------------------------------------------------------
//
const scale = ref(1);
const scale = ref(0.9);
//
function zoomIn() {
if (scale.value < 3) {
if (scale.value < 4) {
// 3
scale.value += 0.1;
}
@ -721,8 +737,8 @@
props.nowShowImageData.width > 1040 &&
props.nowShowImageData.height > 800
) {
imageHeight.value = 800;
imageWidth.value = (800 / props.nowShowImageData.height) * props.nowShowImageData.width;
imageWidth.value = 1040;
imageHeight.value = (1040 / props.nowShowImageData.width) * props.nowShowImageData.height;
} else {
imageHeight.value = 800;
imageWidth.value = 1040;
@ -736,22 +752,24 @@
if (
props.nowShowImageData.width &&
props.nowShowImageData.height &&
props.nowShowImageData.width > 720 &&
props.nowShowImageData.height > 553
props.nowShowImageData.width > 1040 &&
props.nowShowImageData.height > 800
) {
imageWidth.value = props.nowShowImageData.width;
imageHeight.value = props.nowShowImageData.height;
scale.value = props.nowShowImageData.width / 1040;
// imageWidth.value = props.nowShowImageData.width;
// imageHeight.value = props.nowShowImageData.height;
} else {
imageWidth.value = 1440;
imageHeight.value = 1106;
scale.value = 2;
// imageWidth.value = 2080;
// imageHeight.value = 1600;
}
}
//
function refresh() {
scale.value = 1;
scale.value = 0.9;
rotationAngle.value = 0;
graffitiFlag.value = false;
// graffitiFlag.value = false;
getImageWidthAndHeight();
//
const dragDocument: any = document.querySelector('.dragModal');
@ -759,6 +777,7 @@
dragDocument.style.left = 0 + 'px';
dragDocument.style.top = 0 + 'px';
}
document.body.style.cursor = 'default';
}
//
function handlerLocation() {
@ -784,13 +803,15 @@
createMessage.success('在地图上取消加载成功');
}
emits('funUpdateDisplayOrShowOnMapData', props.nowShowImageData);
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
}
// -----------------------------------------------
function setNowShowImageData(value) {
emits('setNowShowImageData', value);
graffitiFlag.value = false;
refresh();
}
// or-------------------------------------------------
@ -798,6 +819,7 @@
const graffitiFlag = ref(false);
//
function setGraffiti() {
refresh();
graffitiFlag.value = !graffitiFlag.value;
if (graffitiFlag.value) {
document.body.style.cursor = 'crosshair';
@ -848,7 +870,7 @@
}).then((res) => {
addFileTagsFlag.value = true;
newFileTagsName.value = '';
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
} else {
return createMessage.error('此标签已存在!');
@ -875,7 +897,7 @@
display: props.nowShowImageData.display,
showOnMap: props.nowShowImageData.showOnMap,
}).then((res) => {
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
},
onCancel: () => {},
@ -904,7 +926,7 @@
display: props.nowShowImageData.display,
showOnMap: props.nowShowImageData.showOnMap,
}).then((res) => {
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
}
//
@ -921,7 +943,7 @@
display: props.nowShowImageData.display,
showOnMap: props.nowShowImageData.showOnMap,
}).then((res) => {
emits('handleSuccessPath');
emits('handleSuccessPath', props.nowShowImageData);
});
}
@ -941,7 +963,23 @@
//
function onMouseDown(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
if (!graffitiFlag.value) {
{
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = true;
initialMouseX = event.clientX;
initialMouseY = event.clientY;
initialDocumentX = dragDocument.offsetLeft;
initialDocumentY = dragDocument.offsetTop;
dragDocument.style.cursor = 'grabbing';
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
}
} else if (
graffitiFlag.value &&
(graffitis.value.length == 0 || !graffitis.value.some((item) => item.status != 'success'))
) {
//
if (nowGraffiti.value != -1) return;
if (graffitis.value.findIndex((item) => item.status == 'mouse') != -1) return;
@ -961,73 +999,66 @@
status: 'edit',
});
graffitisClone.value = cloneDeep(graffitis.value);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('mousemove', onMouseMoveGraffit);
window.addEventListener('mouseup', onMouseUpGraffit);
}
}
// -
function onMouseMoveGraffit(event) {
//
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
setMouseData();
}
// -
function onMouseUpGraffit(event) {
//
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (event.x > rect.right || event.y > rect.bottom) {
graffitis.value.splice(graffitis.value.length - 1, 1);
nowGraffiti.value = -1;
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = true;
initialMouseX = event.clientX;
initialMouseY = event.clientY;
initialDocumentX = dragDocument.offsetLeft;
initialDocumentY = dragDocument.offsetTop;
dragDocument.style.cursor = 'grabbing';
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
setMouseData();
nowGraffiti.value = graffitis.value.length - 1;
}
window.removeEventListener('mousemove', onMouseMoveGraffit);
window.removeEventListener('mouseup', onMouseUpGraffit);
}
//
function onMouseMove(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
//
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
setMouseData();
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
if (isDragging.value) {
const deltaX = event.clientX - initialMouseX;
const deltaY = event.clientY - initialMouseY;
dragDocument.style.left = initialDocumentX + deltaX + 'px';
dragDocument.style.top = initialDocumentY + deltaY + 'px';
}
//
const dragDocument: any = document.querySelector('.dragModal');
if (isDragging.value) {
const deltaX = event.clientX - initialMouseX;
const deltaY = event.clientY - initialMouseY;
dragDocument.style.left = initialDocumentX + deltaX + 'px';
dragDocument.style.top = initialDocumentY + deltaY + 'px';
}
}
//
function onMouseUp(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
//
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (event.x > rect.right || event.y > rect.bottom) {
graffitis.value.splice(graffitis.value.length - 1, 1);
nowGraffiti.value = -1;
} else {
setMouseData();
nowGraffiti.value = graffitis.value.length - 1;
}
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = false;
// dragDocument.style.cursor = 'default';
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = false;
if (dragDocument) {
dragDocument.style.cursor = 'default';
}
}
//
@ -1061,82 +1092,92 @@
//------------------------------------------------------------------------
//
function mouseenter(rect, type) {
// if (rect.status != 'edit') {
// rect.status = 'mouse';
// document.body.style.cursor = 'pointer';
// }
// if (rect.status == 'edit') {
// if (type == 'top' || type == 'bottom') {
// document.body.style.cursor = 'ns-resize';
// }
// if (type == 'left' || type == 'right') {
// document.body.style.cursor = 'ew-resize';
// }
// if (type == 'leftTop' || type == 'rightBottom') {
// document.body.style.cursor = 'nwse-resize';
// }
// if (type == 'leftBottom' || type == 'rightTop') {
// document.body.style.cursor = 'nesw-resize';
// }
// }
if (graffitiFlag.value) {
//
if (rect.status != 'edit') {
rect.status = 'mouse';
document.body.style.cursor = 'pointer';
}
//
if (rect.status == 'edit') {
if (type == 'top' || type == 'bottom') {
document.body.style.cursor = 'ns-resize';
}
if (type == 'left' || type == 'right') {
document.body.style.cursor = 'ew-resize';
}
if (type == 'leftTop' || type == 'rightBottom') {
document.body.style.cursor = 'nwse-resize';
}
if (type == 'leftBottom' || type == 'rightTop') {
document.body.style.cursor = 'nesw-resize';
}
}
}
}
//
function mouseleave(rect) {
// if (rect.status == 'mouse' || rect.status == 'edit') {
// if (rect.status == 'mouse') {
// rect.status = 'success';
// }
// if (graffitiFlag.value) {
// document.body.style.cursor = 'crosshair';
// } else {
// document.body.style.cursor = 'pointer';
// }
// }
if (graffitiFlag.value) {
if (rect.status == 'mouse' || rect.status == 'edit') {
if (rect.status == 'mouse') {
rect.status = 'success';
}
if (rect.status == 'edit') {
document.body.style.cursor = 'crosshair';
}
}
}
}
//
const mouseEditType = ref('');
function funMouseDownEdit(e, index, type) {
//
// graffitisClone.value = cloneDeep(graffitis.value);
// const rect = mouseCanvasRef.value.getBoundingClientRect();
// startX = e.x - rect.x;
// startY = e.y - rect.y;
// isDragging.value = true;
// nowGraffiti.value = index;
// mouseEditType.value = type;
// window.addEventListener('mousemove', funMouseMoveEdit);
// window.addEventListener('mouseup', funMouseUpEdit);
if (graffitiFlag.value) {
//
graffitisClone.value = cloneDeep(graffitis.value);
const rect = mouseCanvasRef.value.getBoundingClientRect();
startX = e.x - rect.x;
startY = e.y - rect.y;
isDragging.value = true;
nowGraffiti.value = index;
mouseEditType.value = type;
window.addEventListener('mousemove', funMouseMoveEdit);
window.addEventListener('mouseup', funMouseUpEdit);
}
}
//
function funMouseMoveEdit(e) {
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
if (graffitiFlag.value) {
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
funSetMouseDataEdit();
}
funSetMouseDataEdit();
}
//
function funMouseUpEdit(e) {
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (e.x > rect.right || e.y > rect.bottom) {
graffitis.value[nowGraffiti.value] = graffitisClone.value[nowGraffiti.value];
} else {
funSetMouseDataEdit();
if (graffitiFlag.value) {
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (e.x > rect.right || e.y > rect.bottom) {
graffitis.value[nowGraffiti.value] = graffitisClone.value[nowGraffiti.value];
} else {
funSetMouseDataEdit();
}
window.removeEventListener('mousemove', funMouseMoveEdit);
window.removeEventListener('mouseup', funMouseUpEdit);
}
window.removeEventListener('mousemove', funMouseMoveEdit);
window.removeEventListener('mouseup', funMouseUpEdit);
}
//
function funSetMouseDataEdit() {

@ -8,7 +8,7 @@
>
<div class="leftMenu_closeButton">
<a-tooltip placement="right">
<template #title> 关闭弹窗 </template>
<template #title> 关闭路径弹窗 </template>
<CloseOutlined
style="font-size: 24px; margin: 8px; color: white"
@click="closePathModal"
@ -85,6 +85,14 @@
</div>
<a-tooltip placement="top">
<template #title>
<div>
<img
:src="VITE_MEDIALIBRARY_IMAGE_URL + show.minipic"
loading="lazy"
width="230"
height="190"
/>
</div>
<div> {{ show.name }}</div>
</template>
<div
@ -173,6 +181,8 @@
import { cloneDeep } from 'lodash-es';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
import { getAppEnvConfig } from '@/utils/env';
const { VITE_MEDIALIBRARY_IMAGE_URL } = getAppEnvConfig();
const props = defineProps(['leftMenuShow', 'floderName', 'allImageDataList', 'nowShowImageData']);
const emits = defineEmits([

@ -42,7 +42,7 @@
});
//
// -
let bottomPointGraphicData: any = [];
// let bottomPointGraphicData: any = [];
// -
let flightointGraphicData: any = [];
// -线
@ -292,15 +292,15 @@
(newValue) => {
if (newValue) {
// -
bottomPointGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_bottom') {
if (newValue.showOnMap == 1) {
graphicLayer.show = newValue.display == 1 ? true : false;
} else {
graphicLayers.removeGraphic(graphicLayer);
}
}
});
// bottomPointGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_bottom') {
// if (newValue.showOnMap == 1) {
// graphicLayer.show = newValue.display == 1 ? true : false;
// } else {
// graphicLayers.removeGraphic(graphicLayer);
// }
// }
// });
// -
flightointGraphicData.forEach((graphicLayer) => {
if (graphicLayer.options.id == newValue.id + '_flight') {
@ -345,52 +345,13 @@
},
);
// watch(
// () => props.nowShowImageData,
// (newValue) => {
// if (newValue) {
// // -
// bottomPointGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_bottom') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// }
// });
// // -
// // flightointGraphicData.forEach((graphicLayer) => {
// // if (graphicLayer.options.id == newValue.id + '_flight') {
// // }
// // });
// // -线
// bottomImagePolylineGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_polyline') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// }
// });
// // -
// imageGraphicData.forEach((graphicLayer) => {
// if (graphicLayer.options.id == newValue.id + '_image') {
// graphicLayer.show = newValue.display == 1 ? true : false;
// graphicLayer.setStyle({
// label: {
// text: `${newValue.name}`,
// },
// });
// }
// });
// }
// },
// {
// deep: true,
// },
// );
// --------------------------------------------------------------------
// --
const showAllImageDataList = async () => {
//
bottomPointGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
// bottomPointGraphicData?.forEach((graphicLayer) => {
// graphicLayers.removeGraphic(graphicLayer);
// });
flightointGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
@ -401,7 +362,7 @@
graphicLayers.removeGraphic(graphicLayer);
});
//
bottomPointGraphicData = [];
// bottomPointGraphicData = [];
flightointGraphicData = [];
bottomImagePolylineGraphicData = [];
imageGraphicData = [];
@ -412,10 +373,12 @@
if (item.lng && item.lat && item.absoluteAltitude && item.showOnMap == 1) {
const image = new Image();
image.crossOrigin = 'Anonymous';
// image.src = item.preview_url;
// image.src = VITE_MEDIALIBRARY_IMAGE_URL + item.objectKey;
image.src =
'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871';
if (item.minipic) {
image.src = VITE_MEDIALIBRARY_IMAGE_URL + item.minipic;
} else {
image.src =
'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871';
}
image.onload = () => {
// Canvas
const canvas = document.createElement('canvas');
@ -439,7 +402,6 @@
ctx.strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1); //
// CanvasURL
const dataURL2 = canvas.toDataURL('image/png');
//
let position = [
parseFloat(item.lng),
@ -452,18 +414,18 @@
Cesium.Cartesian3.fromDegrees(position[0], position[1]),
).then((point) => {
//
let bottomPointGraphic = new mars3d.graphic.BillboardEntity({
id: item.id + '_bottom',
position: [position[0], position[1], point.height],
style: {
image: '/src/assets/images/flightoperation/mediaLibraryPoint.png',
clampToGround: true,
scale: 1,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
hasEdit: false,
show: item.display == 1 ? true : false,
});
// let bottomPointGraphic = new mars3d.graphic.BillboardEntity({
// id: item.id + '_bottom',
// position: [position[0], position[1], point.height],
// style: {
// image: '/src/assets/images/flightoperation/mediaLibraryPoint.png',
// clampToGround: true,
// scale: 1,
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// },
// hasEdit: false,
// show: item.display == 1 ? true : false,
// });
if (index + 1 < props.allImageDataList.length) {
const afterItem = props.allImageDataList[index + 1];
let lng = afterItem.lng - item.lng;
@ -593,7 +555,7 @@
}
});
//
graphicLayers.addGraphic(bottomPointGraphic);
// graphicLayers.addGraphic(bottomPointGraphic);
//
graphicLayers.addGraphic(flightointGraphic);
// 线
@ -601,10 +563,53 @@
//
graphicLayers.addGraphic(imageGraphic);
//
bottomPointGraphicData.push(bottomPointGraphic);
// bottomPointGraphicData.push(bottomPointGraphic);
flightointGraphicData.push(flightointGraphic);
bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic);
imageGraphicData.push(imageGraphic);
//
if (props.nowShowImageData && props.nowShowImageData.id) {
//
flightointGraphicData?.forEach((graphicLayer) => {
if (props.nowShowImageData.id + '_flight' == graphicLayer.options.id) {
graphicLayer.show = true;
}
});
// 线
bottomImagePolylineGraphicData?.forEach((graphicLayer) => {
if (props.nowShowImageData.id + '_polyline' == graphicLayer.options.id) {
let defaultPosition = graphicLayer.options.defaultPosition;
let surfaceHeight = graphicLayer.options.surfaceHeight;
graphicLayer.positions = [
Cesium.Cartesian3.fromDegrees(
defaultPosition[0],
defaultPosition[1],
surfaceHeight,
),
Cesium.Cartesian3.fromDegrees(
defaultPosition[0],
defaultPosition[1],
defaultPosition[2] * 2,
),
];
graphicLayer.setStyle({
color: '#2d8cf0',
});
}
});
//
imageGraphicData?.forEach((graphicLayer) => {
if (props.nowShowImageData.id + '_image' == graphicLayer.options.id) {
graphicLayer.setStyle({
image: graphicLayer.options.chooseImage,
label: {
show: true,
},
});
}
});
}
});
};
}

@ -22,4 +22,18 @@ height="18"
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-4.86 8.86l-3 3.87L9 13.14L6 17h12l-3.86-5.14z"
fill="#ffffff"
></path>
</svg>`;
</svg>`;
export const graffiti_svg = `<svg width="25px" height="25px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="作业区域-新增迭代724-展开" transform="translate(-1692, -817)">
<g id="编组-31" transform="translate(1692, 817)">
<rect id="矩形" fill="#FFFFFF00" x="0" y="0" width="30" height="30" rx="2"></rect>
<g id="paint-brush" transform="translate(5, 6)" fill="currentColor" fill-rule="nonzero">
<path d="M20,0.714305923 C20,0.319805655 19.6801943,0 19.2856941,0 C15.3498684,0 11.3113613,4.43851843 9.06844073,7.3778873 C7.44403191,6.88039807 5.67993844,7.18286866 4.31403832,8.1930748 C2.9481382,9.20328093 2.14234655,10.8014718 2.14235192,12.5003537 C2.14235192,15.2575745 0.397659708,16.4942166 0.314621644,16.5513611 C0.0544979202,16.7270112 -0.060485571,17.0518879 0.0312292032,17.352064 C0.122943977,17.6522401 0.39986556,17.8573755 0.713740079,17.8576481 L7.49964635,17.8576481 C9.1985282,17.8576481 10.7967191,17.0518618 11.8069252,15.6859617 C12.8171313,14.3200616 13.1196019,12.5559681 12.6221127,10.9315593 C15.5623745,8.68863867 20,4.65013156 20,0.714305923 Z M7.49964635,16.4290362 L2.37718,16.4290362 C2.97987562,15.572762 3.57096377,14.2789754 3.57096377,12.5003537 C3.57096377,10.3306022 5.32989487,8.57167108 7.49964635,8.57167108 C9.66939782,8.57167108 11.4283289,10.3306022 11.4283289,12.5003537 C11.4283289,14.6701051 9.66939782,16.4290362 7.49964635,16.4290362 Z M10.3943711,7.99576193 C10.7003321,7.59932214 11.0006383,7.22579967 11.2952894,6.87519451 C12.0164936,7.36244905 12.6375509,7.98350636 13.1248055,8.70471055 C12.7736051,8.99876649 12.4000826,9.29907261 12.0042381,9.6056289 C11.58799,8.9608029 11.0391971,8.41201004 10.3943711,7.99576193 Z M14.206979,7.75646944 C13.6677115,6.99555471 13.0035524,6.33139566 12.2426377,5.79212815 C15.080218,2.70900521 17.2204571,1.77415734 18.4838857,1.51432856 C18.2294142,2.77865004 17.2901019,4.91888916 14.206979,7.75646944 L14.206979,7.75646944 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>`

@ -1,210 +1,441 @@
<template>
<div :id="mapId" class="map">
<div ref="vChartRef" id="mars3d-container" class="mars3d-container">
<div class="mapInfo">
<span> {{ props.nowPreviewRecord.lat }}°N</span>
<span> {{ props.nowPreviewRecord.lng }}°E</span>
</div>
</div>
</template>
<script setup lang="ts">
import { defineProps, ref, onMounted, onUnmounted, defineEmits, watch } from 'vue';
import { v4 as uuidv4 } from 'uuid';
import mapboxgl, { Map } from 'mapbox-gl';
import { MapboxConfig, MapboxDefaultStyle } from '@/components/MapboxMaps/src/config';
import axios from 'axios';
import {
ExpandOutlined,
CompressOutlined,
PlusOutlined,
MinusOutlined,
HeatMapOutlined,
} from '@ant-design/icons-vue';
import { cloneDeep } from 'lodash-es';
<script lang="ts" setup>
import { ref, watch, onMounted, defineEmits } from 'vue';
import * as mars3d from 'mars3d';
import * as Cesium from 'mars3d-cesium';
import { getAppEnvConfig } from '@/utils/env';
const { VITE_MEDIALIBRARY_IMAGE_URL } = getAppEnvConfig();
const props = defineProps(['nowPreviewRecord', 'previewRecordList', 'hideOrShowTextboxFlag']);
const emit = defineEmits(['chooseNowPreviewRecord', 'reloadTable']);
const emits = defineEmits(['chooseNowPreviewRecord']);
let map: mars3d.Map; //
let graphicLayers = new mars3d.layer.GraphicLayer();
// -线
let bottomImagePolylineGraphicData: any = [];
// -
let imageGraphicData: any = [];
const vChartRef: any = ref<HTMLElement>();
onMounted(() => {
initMap();
});
// or
watch(
() => props.hideOrShowTextboxFlag,
(newValue) => {
imageGraphicData.forEach((graphic) => {
if (graphic.options.id !== props.nowPreviewRecord.id) {
graphic.setStyle({
show: newValue,
});
}
});
bottomImagePolylineGraphicData.forEach((graphic) => {
if (graphic.options.id !== props.nowPreviewRecord.id + '_polyline') {
graphic.setStyle({
show: newValue,
});
}
});
},
);
const mapId = `modal-map-${uuidv4()}`;
const networkType = ref('WAN');
let map: Map;
// or
watch(
() => props.nowPreviewRecord,
() => {
imageGraphicData.forEach((graphic) => {
if (graphic.options.id !== props.nowPreviewRecord.id) {
graphic.setStyle({
image: graphic.options.defaultImage,
show: props.hideOrShowTextboxFlag,
});
} else {
graphic.setStyle({
image: graphic.options.chooseImage,
show: true,
});
}
});
bottomImagePolylineGraphicData.forEach((graphic) => {
if (graphic.options.id !== props.nowPreviewRecord.id + '_polyline') {
graphic.setStyle({
show: props.hideOrShowTextboxFlag,
});
} else {
graphic.setStyle({
show: true,
});
}
});
},
);
const initMap = () => {
let mapDataSources: any = {
'raster-tiles': {
type: 'raster',
tiles: [
`http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${MapboxConfig.TDT_TOKEN}`,
],
tileSize: 256,
minzoom: 1,
maxzoom: 17,
map = new mars3d.Map(vChartRef.value, {
scene: {
center: {
lat: parseFloat(props.nowPreviewRecord.lat),
lng: parseFloat(props.nowPreviewRecord.lng),
alt: 8306.3,
heading: 360,
pitch: -45,
},
scene3DOnly: false,
shadows: false,
removeDblClick: true,
sceneMode: 3,
showSun: true,
showMoon: true,
showSkyBox: true,
showSkyAtmosphere: true,
fog: true,
fxaa: true,
requestRenderMode: true,
contextOptions: {
requestWebgl1: false,
webgl: {
preserveDrawingBuffer: true,
alpha: false,
stencil: true,
powerPreference: 'high-performance',
},
},
globe: {
depthTestAgainstTerrain: false,
baseColor: '#546a53',
showGroundAtmosphere: true,
enableLighting: false,
},
cameraController: {
zoomFactor: 3,
minimumZoomDistance: 1,
maximumZoomDistance: 50000000,
enableRotate: true,
enableTranslate: true,
enableTilt: true,
enableZoom: true,
enableCollisionDetection: true,
minimumCollisionTerrainHeight: 15000,
},
},
'raster-tiles-font': {
type: 'raster',
tiles: [
`https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=${MapboxConfig.TDT_TOKEN}`,
],
tileSize: 256,
control: {
homeButton: true,
baseLayerPicker: false,
sceneModePicker: false,
vrButton: false,
fullscreenButton: false,
navigationHelpButton: false,
animation: false,
timeline: false,
infoBox: false,
geocoder: false,
selectionIndicator: false,
showRenderLoopErrors: false,
contextmenu: {
hasDefault: false,
},
mouseDownView: false,
zoom: false,
compass: false,
distanceLegend: false,
},
};
let mapDataLayers: any = [
{
id: 'tdt-vec-tiles',
type: 'raster',
source: 'raster-tiles-font',
method: {
templateValues: {
dataServer: '//data.mars3d.cn',
gltfServerUrl: '//data.mars3d.cn/gltf',
},
},
{
id: 'tdt-img-tiles',
type: 'raster',
source: 'raster-tiles',
terrain: {
url: '//data.mars3d.cn/terrain',
show: true,
clip: true,
},
];
map = new mapboxgl.Map({
container: mapId,
language: 'zh-cmn',
projection: 'equirectangular', // wgs84
style: {
glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
version: 8,
sources: mapDataSources,
layers: mapDataLayers,
},
maxZoom: 22,
minZoom: 8,
pitch: 0,
zoom: 14,
center: [parseFloat(props.nowPreviewRecord.lng), parseFloat(props.nowPreviewRecord.lat)],
basemaps: [
{
id: 10,
name: '地图底图',
type: 'group',
opacity: 1,
},
{
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-770c35e7-9054-4259-b5ee-c15f108becd0',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 1,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-3b881368-574b-48a5-88b2-8b3c2c48fd62',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 2,
},
],
show: true,
opacity: 1,
},
],
layers: [],
});
setImage();
if (map) {
map.addLayer(graphicLayers);
//
showAllImageDataList();
const position = Cesium.Cartesian3.fromDegrees(
parseFloat(props.nowPreviewRecord.lng),
parseFloat(props.nowPreviewRecord.lat),
);
map.flyToPoint(position);
}
};
watch(
() => props.hideOrShowTextboxFlag,
(newValue) => {
if (newValue) {
props.previewRecordList.forEach((item) => {
if (!map.getLayer(item.id)) {
const coordinates = [parseFloat(item.lng), parseFloat(item.lat)];
//
map.addLayer({
id: item.id,
type: 'symbol',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: coordinates,
},
},
],
},
},
layout: {
'icon-image': item.id,
'icon-size': 40 / item.width,
//
'icon-allow-overlap': true, //
'icon-ignore-placement': true, //
visibility: 'visible', //
// --
const showAllImageDataList = async () => {
//
imageGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
bottomImagePolylineGraphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
//
imageGraphicData = [];
bottomImagePolylineGraphicData = [];
props.previewRecordList.forEach((item, index) => {
if (item.lng && item.lat && item.absoluteAltitude) {
const image = new Image();
image.crossOrigin = 'Anonymous';
if (item.minipic) {
image.src = VITE_MEDIALIBRARY_IMAGE_URL + item.minipic;
} else {
image.src =
'https://m.tuniucdn.com/fb2/t1/G5/M00/44/52/Cii-s1soezyIF2UxABn76u-yKl8AAIwBgB34jAAGfwC3020871';
}
image.onload = () => {
// Canvas
const canvas = document.createElement('canvas');
canvas.width = 30;
canvas.height = 30;
// Canvas
const ctx = canvas.getContext('2d');
//
ctx.beginPath();
ctx.arc(15, 15, 20, 0, Math.PI * 2, true);
ctx.closePath();
ctx.clip(); //
ctx.fillStyle = '#ffffff00';
ctx?.fillRect(0, 0, canvas.width, canvas.height);
// Canvas
ctx.drawImage(image, 2, 2, 26, 26);
//
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2;
ctx.strokeRect(1, 1, canvas.width - 2, canvas.height - 2);
// CanvasURL
const dataURL1 = canvas.toDataURL('image/png');
// CanvasimageImage
ctx.drawImage(image, 2, 2, 26, 26);
//
ctx.strokeStyle = '#2d8cef'; //
ctx.lineWidth = 2; //
//
ctx.strokeRect(1, 1, canvas.width - 2, canvas.height - 2); //
// CanvasURL
const dataURL2 = canvas.toDataURL('image/png');
//
let position = [
parseFloat(item.lng),
parseFloat(item.lat),
parseFloat(item.absoluteAltitude),
];
//
mars3d.PointUtil.getSurfaceHeight(
map.scene,
Cesium.Cartesian3.fromDegrees(position[0], position[1]),
).then((point) => {
// 线
let bottomImagePolylineGraphic = new mars3d.graphic.PolylineEntity({
id: item.id + '_polyline',
positions: [
Cesium.Cartesian3.fromDegrees(position[0], position[1], point.height),
Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]),
],
style: {
color: '#ffffff',
width: 1, // 线
clampToGround: false,
},
hasEdit: false,
});
}
});
} else {
let filters = cloneDeep(props.previewRecordList).filter(
(item) => item.id != props.nowPreviewRecord.id,
);
filters.forEach((fl) => {
if (map.getLayer(fl.id)) {
map.removeLayer(fl.id);
}
if (map.getSource(fl.id)) {
map.removeSource(fl.id);
}
});
}
},
);
function setImage() {
props.previewRecordList.forEach((item) => {
map.on('style.load', () => {
map.loadImage(item.url, (error, image) => {
if (error) {
console.error('加载图片失败:', error.message);
return;
}
if (!map.hasImage(item.id)) {
map.addImage(item.id, image);
}
const coordinates = [parseFloat(item.lng), parseFloat(item.lat)];
if (!map.getLayer(item.id)) {
//
map.addLayer({
//
let imageGraphic = new mars3d.graphic.BillboardEntity({
id: item.id,
type: 'symbol',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: coordinates,
},
},
],
},
},
layout: {
'icon-image': item.id,
'icon-size': 40 / item.width,
//
'icon-allow-overlap': true, //
'icon-ignore-placement': true, //
visibility: 'visible', //
position: [position[0], position[1], position[2]],
style: {
image: item.id == props.nowPreviewRecord.id ? dataURL2 : dataURL1,
clampToGround: false,
scale: 1,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
},
hasEdit: false,
//
defaultImage: dataURL1,
//
chooseImage: dataURL2,
});
map.on('click', item.id, function (e) {
clickHandler(item);
//
imageGraphic.on(mars3d.EventType.click, function () {
if (props.nowPreviewRecord.id !== item.id) {
clickSetImage(item);
}
});
}
});
});
});
}
onMounted(() => {
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
//
initMap();
});
onUnmounted(() => {
map && map.remove();
props.previewRecordList.forEach((item) => {
map.off('click', item.id, function (e) {
clickHandler(item);
});
//
graphicLayers.addGraphic(bottomImagePolylineGraphic);
graphicLayers.addGraphic(imageGraphic);
//
bottomImagePolylineGraphicData.push(bottomImagePolylineGraphic);
imageGraphicData.push(imageGraphic);
});
};
}
});
});
};
//
function clickHandler(item) {
emit('chooseNowPreviewRecord', item);
function clickSetImage(item) {
imageGraphicData.forEach((graphic) => {
if (graphic.options.id == item.id) {
graphic.setStyle({
image: graphic.options.chooseImage,
});
emits('chooseNowPreviewRecord', item);
} else {
graphic.setStyle({
image: graphic.options.defaultImage,
});
}
});
}
</script>
<style lang="less" scoped>
.map {
.mars3d-container {
position: relative;
width: 100%;
height: 100%;
@ -233,8 +464,4 @@
margin-left: 10px;
}
}
::v-deep .mapboxgl-ctrl {
display: none !important;
}
</style>

@ -18,7 +18,12 @@
<div class="mainBody">
<div class="imgOrVideo">
<!-- 图片 -->
<div class="imageDiv" v-if="props.nowPreviewRecord.objectKey">
<div
class="imageDiv"
v-if="
props.nowPreviewRecord.objectKey && props.nowPreviewRecord.objectKey.includes('jpeg')
"
>
<PreviewImage
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@ -28,7 +33,12 @@
/>
</div>
<!-- 视频 -->
<div class="videoDiv" v-if="props.nowPreviewRecord.type == 'video'">
<div
class="videoDiv"
v-if="
props.nowPreviewRecord.objectKey && props.nowPreviewRecord.objectKey.includes('mp4')
"
>
<PreviewVideo
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@ -39,15 +49,20 @@
</div>
<div class="information">
<PreviewImageInformation
v-if="props.nowPreviewRecord.objectKey"
v-if="
props.nowPreviewRecord.objectKey && props.nowPreviewRecord.objectKey.includes('jpeg')
"
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@chooseNowPreviewRecord="chooseNowPreviewRecord"
@handleSuccess="handleSuccess"
:hideOrShowTextboxFlag="hideOrShowTextboxFlag"
@openPathModal="openPathModal"
/>
<PreviewVideoInformation
v-if="props.nowPreviewRecord.type == 'video'"
v-if="
props.nowPreviewRecord.objectKey && props.nowPreviewRecord.objectKey.includes('mp4')
"
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@chooseNowPreviewRecord="chooseNowPreviewRecord"
@ -68,7 +83,12 @@
} from './preview';
const props = defineProps(['nowPreviewRecord', 'previewRecordList']);
const emit = defineEmits(['closeModal', 'chooseNowPreviewRecord', 'handleSuccess']);
const emits = defineEmits([
'closeModal',
'chooseNowPreviewRecord',
'handleSuccess',
'openPathModal',
]);
const hideOrShowTextboxFlag = ref(true);
function setHideOrShowTextboxFlag(value) {
@ -77,22 +97,26 @@
//
function chooseNowPreviewRecord(value) {
emit('chooseNowPreviewRecord', value);
emits('chooseNowPreviewRecord', value);
}
//
function handleSuccess(record = null) {
emit('handleSuccess', record);
emits('handleSuccess', record);
}
//
function closeModal() {
document.body.style.cursor = 'default';
emit('closeModal');
emits('closeModal');
}
//
function openPathModal(value) {
emits('openPathModal', value);
}
</script>
<style lang="less" scoped>
.modal {
width: 100%;
height: 920px;
height: 100%;
//
-webkit-user-select: none; /* Safari */
@ -124,7 +148,7 @@
}
.mainBody {
width: 100%;
height: 920px;
height: 100%;
display: flex;
position: absolute;
top: 0px;
@ -132,7 +156,7 @@
.imgOrVideo {
width: 80%;
height: 920px;
height: 100%;
background: #101010;
.imageDiv {

@ -1,321 +0,0 @@
<template>
<div ref="vChartRef" id="mars3d-container" class="mars3d-container">
<div class="mapInfo">
<span> {{ props.nowPreviewRecord.lat }}°N</span>
<span> {{ props.nowPreviewRecord.lng }}°E</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, defineEmits } from 'vue';
import * as mars3d from 'mars3d';
import * as Cesium from 'mars3d-cesium';
const props = defineProps(['nowPreviewRecord', 'previewRecordList', 'hideOrShowTextboxFlag']);
const emits = defineEmits(['chooseNowPreviewRecord', 'reloadTable', 'mapOnLoad']);
let map: mars3d.Map; //
let graphicData: any = [];
let graphicLayers = new mars3d.layer.GraphicLayer();
const vChartRef: any = ref<HTMLElement>();
onMounted(() => {
initMap();
addImage();
});
const initMap = () => {
map = new mars3d.Map(vChartRef.value, {
scene: {
center: {
lat: parseFloat(props.nowPreviewRecord.lat),
lng: parseFloat(props.nowPreviewRecord.lng),
alt: 8306.3,
heading: 360,
pitch: -45,
},
scene3DOnly: false,
shadows: false,
removeDblClick: true,
sceneMode: 3,
showSun: true,
showMoon: true,
showSkyBox: true,
showSkyAtmosphere: true,
fog: true,
fxaa: true,
requestRenderMode: true,
contextOptions: {
requestWebgl1: false,
webgl: {
preserveDrawingBuffer: true,
alpha: false,
stencil: true,
powerPreference: 'high-performance',
},
},
globe: {
depthTestAgainstTerrain: false,
baseColor: '#546a53',
showGroundAtmosphere: true,
enableLighting: false,
},
cameraController: {
zoomFactor: 3,
minimumZoomDistance: 1,
maximumZoomDistance: 50000000,
enableRotate: true,
enableTranslate: true,
enableTilt: true,
enableZoom: true,
enableCollisionDetection: true,
minimumCollisionTerrainHeight: 15000,
},
},
control: {
homeButton: true,
baseLayerPicker: false,
sceneModePicker: false,
vrButton: false,
fullscreenButton: false,
navigationHelpButton: false,
animation: false,
timeline: false,
infoBox: false,
geocoder: false,
selectionIndicator: false,
showRenderLoopErrors: false,
contextmenu: {
hasDefault: false,
},
mouseDownView: false,
zoom: false,
compass: false,
distanceLegend: false,
},
method: {
templateValues: {
dataServer: '//data.mars3d.cn',
gltfServerUrl: '//data.mars3d.cn/gltf',
},
},
terrain: {
url: '//data.mars3d.cn/terrain',
show: true,
clip: true,
},
basemaps: [
{
id: 10,
name: '地图底图',
type: 'group',
opacity: 1,
},
{
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-770c35e7-9054-4259-b5ee-c15f108becd0',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 1,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
eventParent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
private: false,
id: 'm-3b881368-574b-48a5-88b2-8b3c2c48fd62',
opacity: 1,
pid: 2021,
parent: {
id: 2021,
pid: 10,
name: '天地图影像',
icon: 'https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png',
type: 'group',
layers: [
{
name: '底图',
type: 'tdt',
layer: 'img_d',
show: true,
},
{
name: '注记',
type: 'tdt',
layer: 'img_z',
show: true,
},
],
show: true,
},
zIndex: 2,
},
],
show: true,
opacity: 1,
},
],
layers: [],
});
emits('mapOnLoad', map);
};
const addImage = () => {
//
graphicData?.forEach((graphicLayer) => {
graphicLayers.removeGraphic(graphicLayer);
});
//
map.addLayer(graphicLayers);
//
graphicData = [];
props.previewRecordList.forEach((item) => {
let graphic = new mars3d.graphic.BillboardEntity({
id: item.id,
position: [parseFloat(item.lng), parseFloat(item.lat)],
style: {
// image: '@/assets/images/point.png',
image: '../point.png',
clampToGround: true,
scale: 1,
label: {
text: item.name,
font_size: 12,
color: '#ffffff',
pixelOffsetY: -30,
pixelOffsetX: 0,
distanceDisplayCondition: true,
distanceDisplayCondition_far: 6000,
distanceDisplayCondition_near: 0,
},
},
popup: `<div class="marsTiltPanel marsTiltPanel-theme-green">
<div style="postion: relative; padding: 60px; max-width: 500px; overflow: hidden;">
</div>
<div style="position: absolute; bottom: 0; left: 0; width: 85px; height: 2px; transform: rotate(-45deg) translate(15px, -25px); background-color: #15babc;" ></div>
</div>`,
popupOptions: {
offsetY: 0,
offsetX: 0,
template: '{content}',
horizontalOrigin: 'Cesium.HorizontalOrigin.LEFT',
verticalOrigin: 'Cesium.VerticalOrigin.CENTER',
},
pointerEvents: true,
});
//
graphicLayers.addGraphic(graphic);
graphicData.push(graphic);
});
};
</script>
<style lang="less" scoped>
.mars3d-container {
position: relative;
width: 100%;
height: 100%;
}
.mapInfo {
position: absolute;
width: 100%;
height: 30px;
bottom: 0px;
left: 0px;
background: #3d3f3aaa;
z-index: 1000;
display: flex;
justify-content: flex-start;
span {
height: 100%;
width: 30%;
color: #ffffff;
display: flex;
align-items: center;
justify-content: flex-start;
font-size: 15px;
margin-left: 10px;
}
}
</style>

@ -2,5 +2,34 @@ export { default as PreviewImage } from './previewImage.vue';
export { default as PreviewVideo } from './previewVideo.vue';
export { default as PreviewImageInformation } from './previewImageInformation.vue';
export { default as PreviewVideoInformation } from './previewVideoInformation.vue';
// export { default as Map } from './Map.vue';
export { default as Map } from './map2.vue';
export { default as Map } from './map.vue';
export const graffiti_svg = `<svg width="25px" height="25px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="作业区域-新增迭代724-展开" transform="translate(-1692, -817)">
<g id="编组-31" transform="translate(1692, 817)">
<rect id="矩形" fill="#FFFFFF00" x="0" y="0" width="30" height="30" rx="2"></rect>
<g id="paint-brush" transform="translate(5, 6)" fill="currentColor" fill-rule="nonzero">
<path d="M20,0.714305923 C20,0.319805655 19.6801943,0 19.2856941,0 C15.3498684,0 11.3113613,4.43851843 9.06844073,7.3778873 C7.44403191,6.88039807 5.67993844,7.18286866 4.31403832,8.1930748 C2.9481382,9.20328093 2.14234655,10.8014718 2.14235192,12.5003537 C2.14235192,15.2575745 0.397659708,16.4942166 0.314621644,16.5513611 C0.0544979202,16.7270112 -0.060485571,17.0518879 0.0312292032,17.352064 C0.122943977,17.6522401 0.39986556,17.8573755 0.713740079,17.8576481 L7.49964635,17.8576481 C9.1985282,17.8576481 10.7967191,17.0518618 11.8069252,15.6859617 C12.8171313,14.3200616 13.1196019,12.5559681 12.6221127,10.9315593 C15.5623745,8.68863867 20,4.65013156 20,0.714305923 Z M7.49964635,16.4290362 L2.37718,16.4290362 C2.97987562,15.572762 3.57096377,14.2789754 3.57096377,12.5003537 C3.57096377,10.3306022 5.32989487,8.57167108 7.49964635,8.57167108 C9.66939782,8.57167108 11.4283289,10.3306022 11.4283289,12.5003537 C11.4283289,14.6701051 9.66939782,16.4290362 7.49964635,16.4290362 Z M10.3943711,7.99576193 C10.7003321,7.59932214 11.0006383,7.22579967 11.2952894,6.87519451 C12.0164936,7.36244905 12.6375509,7.98350636 13.1248055,8.70471055 C12.7736051,8.99876649 12.4000826,9.29907261 12.0042381,9.6056289 C11.58799,8.9608029 11.0391971,8.41201004 10.3943711,7.99576193 Z M14.206979,7.75646944 C13.6677115,6.99555471 13.0035524,6.33139566 12.2426377,5.79212815 C15.080218,2.70900521 17.2204571,1.77415734 18.4838857,1.51432856 C18.2294142,2.77865004 17.2901019,4.91888916 14.206979,7.75646944 L14.206979,7.75646944 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>`
export const otherimage_svg = `<svg width="23px" height="23px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="作业区域-新增迭代724-展开" transform="translate(-1692, -857)">
<g id="编组-30" transform="translate(1692, 857)">
<rect id="矩形" fill="#FFFFFF00" x="0" y="0" width="30" height="30" rx="2"></rect>
<g id="pencil-simple" transform="translate(4.8766, 6)" fill="currentColor">
<path d="M19.7015397,4.44403083 L15.680296,0.421887073 C15.4102312,0.151760637 15.0439078,0 14.6619349,0 C14.279962,0 13.9136386,0.151760637 13.6435738,0.421887073 L2.5455531,11.5208078 C2.27427322,11.7899334 2.12222767,12.1565934 2.12344121,12.5387189 L2.12344121,16.5608626 C2.12344121,17.3561613 2.76816548,18.0008856 3.56346417,18.0008856 L7.58560792,18.0008856 C7.96773341,18.0020991 8.33439336,17.8500536 8.60351899,17.5787737 L19.7015397,6.48075298 C19.9716662,6.21068821 20.1234268,5.84436477 20.1234268,5.4623919 C20.1234268,5.08041904 19.9716662,4.71409559 19.7015397,4.44403083 Z M7.58560792,16.5608626 L3.56346417,16.5608626 L3.56346417,12.5387189 L11.4835503,4.61863272 L15.5056941,8.64077648 L7.58560792,16.5608626 Z M16.5236051,7.62196539 L12.5014614,3.60072165 L14.6614849,1.44069816 L18.6836286,5.4619419 L16.5236051,7.62196539 Z" id="形状" fill-rule="nonzero"></path>
<line x1="1.123434" y1="17.5" x2="18.876566" y2="17.5" id="路径-6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></line>
<line x1="-0.876566" y1="17.5" x2="1.876566" y2="17.5" id="路径-6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" transform="translate(0.5, 17.5) scale(-1, -1) rotate(90) translate(-0.5, -17.5)"></line>
<line x1="17.623434" y1="17.5" x2="20.376566" y2="17.5" id="路径-6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" transform="translate(19, 17.5) scale(-1, -1) rotate(90) translate(-19, -17.5)"></line>
</g>
</g>
</g>
</g>
</svg>`;

@ -64,9 +64,16 @@
<CloseOutlined
style="margin-right: 10px; padding: 3px; color: red"
@click="
rect.text ? (rect.text = graffitisClone[index].text) : (rect.text = '');
rect.text
? ((rect.x = graffitisClone[index].x),
(rect.y = graffitisClone[index].y),
(rect.width = graffitisClone[index].width),
(rect.height = graffitisClone[index].height),
(rect.color = graffitisClone[index].color),
(rect.text = graffitisClone[index].text),
(rect.status = 'success'))
: graffitis.splice(index, 1);
nowGraffiti = -1;
rect.status = 'success';
"
/>
<DeleteOutlined
@ -107,12 +114,14 @@
:style="{
textDecoration: rect.status == 'mouse' ? 'underline' : '',
}"
@mouseenter="rect.status != 'edit' ? (rect.status = 'mouse') : ''"
@mouseleave="rect.status == 'mouse' ? (rect.status = 'success') : ''"
@mouseenter="graffitiFlag && rect.status != 'edit' ? (rect.status = 'mouse') : ''"
@mouseleave="graffitiFlag && rect.status == 'mouse' ? (rect.status = 'success') : ''"
@click="
rect.status = 'edit';
graffitisClone = cloneDeep(graffitis);
nowGraffiti = index;
graffitiFlag
? ((rect.status = 'edit'),
(graffitisClone = cloneDeep(graffitis)),
(nowGraffiti = index))
: ''
"
>
{{ rect.text }}
@ -131,10 +140,7 @@
}"
@mouseenter="mouseenter(rect, 'top')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'top')"
/>
<!-- -->
@ -150,10 +156,7 @@
}"
@mouseenter="mouseenter(rect, 'bottom')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'bottom')"
/>
<!-- -->
@ -169,10 +172,7 @@
}"
@mouseenter="mouseenter(rect, 'right')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'right')"
/>
<!-- -->
@ -188,10 +188,7 @@
}"
@mouseenter="mouseenter(rect, 'left')"
@mouseleave="mouseleave(rect)"
@click="
rect.status = 'edit';
nowGraffiti = index;
"
@click="graffitiFlag ? ((rect.status = 'edit'), (nowGraffiti = index)) : ''"
@mousedown="funMouseDownEdit($event, index, 'left')"
/>
<!-- 左上 -->
@ -400,7 +397,7 @@
:class="li.id == props.nowPreviewRecord.id ? 'bottom_div_choose' : 'bottom_div'"
>
<img
:src="VITE_MEDIALIBRARY_IMAGE_URL + li.objectKey"
:src="VITE_MEDIALIBRARY_IMAGE_URL + (li.minipic ? li.minipic : li.objectKey)"
loading="lazy"
:width="60"
:height="35"
@ -449,19 +446,26 @@
<template #title>
<span>{{ hideOrShowGraffitiFlag ? '点击隐藏涂鸦信息' : '点击显示涂鸦信息' }}</span>
</template>
<EyeOutlined @click="hideOrShowGraffiti(false)" v-if="hideOrShowGraffitiFlag" />
<EyeInvisibleOutlined @click="hideOrShowGraffiti(true)" v-if="!hideOrShowGraffitiFlag" />
<div
style="
position: absolute;
bottom: 0px;
right: 0px;
font-size: 10px;
color: #000000;
pointer-events: none;
"
>
涂鸦
<EyeOutlined
@click="hideOrShowGraffiti(false)"
v-if="hideOrShowGraffitiFlag"
style="color: #2d8cf0"
/>
<EyeInvisibleOutlined
@click="hideOrShowGraffiti(true)"
v-if="!hideOrShowGraffitiFlag"
style="color: #595959"
/>
<div style="position: absolute; bottom: -12px; right: -4px; pointer-events: none">
<div
v-html="
`${
hideOrShowGraffitiFlag
? graffiti_svg.replaceAll('currentColor', '#2d8cf0')
: graffiti_svg.replaceAll('currentColor', '#595959')
}`
"
/>
</div>
</a-tooltip>
</div>
@ -476,19 +480,26 @@
}}
</span>
</template>
<EyeOutlined @click="hideOrShowTextbox(false)" v-if="hideOrShowTextboxFlag" />
<EyeInvisibleOutlined @click="hideOrShowTextbox(true)" v-if="!hideOrShowTextboxFlag" />
<div
style="
position: absolute;
bottom: 0px;
right: 0px;
font-size: 10px;
color: #000000;
pointer-events: none;
"
>
标注
<EyeOutlined
@click="hideOrShowTextbox(false)"
v-if="hideOrShowTextboxFlag"
style="color: #2d8cf0"
/>
<EyeInvisibleOutlined
@click="hideOrShowTextbox(true)"
v-if="!hideOrShowTextboxFlag"
style="color: #595959"
/>
<div style="position: absolute; bottom: -10px; right: -3px; pointer-events: none">
<div
v-html="
`${
hideOrShowTextboxFlag
? otherimage_svg.replaceAll('currentColor', '#2d8cf0')
: otherimage_svg.replaceAll('currentColor', '#595959')
}`
"
/>
</div>
</a-tooltip>
</div>
@ -521,17 +532,12 @@
FontColorsOutlined,
RedoOutlined,
OneToOneOutlined,
FileImageOutlined,
BorderHorizontalOutlined,
ExpandOutlined,
CompressOutlined,
} from '@ant-design/icons-vue';
import {
UpdatePicStatus,
Deletepic,
UpdatePicName,
UpdatePicParentKey,
} from '@/api/demo/mediaLibrary';
import { UpdatePicStatus, Deletepic } from '@/api/demo/mediaLibrary';
import { graffiti_svg, otherimage_svg } from './preview';
import { useMessage } from '@/hooks/web/useMessage';
import { cloneDeep } from 'lodash-es';
import { getAppEnvConfig } from '@/utils/env';
@ -547,7 +553,9 @@
//
function clickLeftOrRightButton(direction) {
const list = props.previewRecordList.filter((item) => item.objectKey);
const list = props.previewRecordList.filter(
(item) => item.objectKey && item.objectKey.includes('jpeg'),
);
graffitiFlag.value = false;
for (let index = 0; index < list.length; index++) {
if (list[index].id == props.nowPreviewRecord.id) {
@ -572,6 +580,7 @@
//
function chooseNowPreviewRecord(value) {
emits('chooseNowPreviewRecord', value);
graffitiFlag.value = false;
refresh();
}
//
@ -582,7 +591,7 @@
const scale = ref(1);
//
function zoomIn() {
if (scale.value < 3) {
if (scale.value < 4) {
scale.value += 0.1;
}
}
@ -615,8 +624,8 @@
props.nowPreviewRecord.width > 1040 &&
props.nowPreviewRecord.height > 800
) {
imageHeight.value = 800;
imageWidth.value = (800 / props.nowPreviewRecord.height) * props.nowPreviewRecord.width;
imageWidth.value = 1040;
imageHeight.value = (1040 / props.nowPreviewRecord.width) * props.nowPreviewRecord.height;
} else {
imageHeight.value = 800;
imageWidth.value = 1040;
@ -634,11 +643,13 @@
props.nowPreviewRecord.width > 1040 &&
props.nowPreviewRecord.height > 800
) {
imageWidth.value = props.nowPreviewRecord.width;
imageHeight.value = props.nowPreviewRecord.height;
scale.value = props.nowPreviewRecord.width / 1040;
// imageWidth.value = props.nowPreviewRecord.width;
// imageHeight.value = props.nowPreviewRecord.height;
} else {
imageWidth.value = 2080;
imageHeight.value = 1600;
scale.value = 2;
// imageWidth.value = 2080;
// imageHeight.value = 1600;
}
}
@ -646,7 +657,7 @@
function refresh() {
scale.value = 1;
rotationAngle.value = 0;
graffitiFlag.value = false;
// graffitiFlag.value = false;
getImageWidthAndHeight();
//
const dragDocument: any = document.querySelector('.dragModal');
@ -654,11 +665,12 @@
dragDocument.style.left = 0 + 'px';
dragDocument.style.top = 0 + 'px';
}
document.body.style.cursor = 'default';
}
//
function deleteImage() {
let content = '确定要删除选择的文件/文件夹吗?';
let content = '确定要删除选择的文件吗?';
if (props.previewRecordList.length == 1) {
content = '下列图片只有一个,删除此图片后将会关闭此弹窗,确定要删除选择的文件吗?';
}
@ -672,7 +684,7 @@
ids: ids,
}).then((res) => {
handleSuccess(props.nowPreviewRecord);
createMessage.success(res);
createMessage.success('删除成功');
});
},
});
@ -754,6 +766,7 @@
const nowMouseGraffiti = ref(0);
//
function setGraffiti() {
refresh();
graffitiFlag.value = !graffitiFlag.value;
if (graffitiFlag.value) {
document.body.style.cursor = 'crosshair';
@ -832,7 +845,21 @@
const mouseCanvasRef = ref();
//
function onMouseDown(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
if (!graffitiFlag.value) {
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = true;
initialMouseX = event.clientX;
initialMouseY = event.clientY;
initialDocumentX = dragDocument.offsetLeft;
initialDocumentY = dragDocument.offsetTop;
dragDocument.style.cursor = 'grabbing';
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
} else if (
graffitiFlag.value &&
(graffitis.value.length == 0 || !graffitis.value?.some((item) => item.status != 'success'))
) {
//
if (nowGraffiti.value != -1) return;
if (graffitis.value.findIndex((item) => item.status == 'mouse') != -1) return;
@ -852,71 +879,64 @@
status: 'edit',
});
graffitisClone.value = cloneDeep(graffitis.value);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('mousemove', onMouseMoveGraffit);
window.addEventListener('mouseup', onMouseUpGraffit);
}
}
// -
function onMouseMoveGraffit(event) {
//
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
setMouseData();
}
// -
function onMouseUpGraffit(event) {
//
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (event.x > rect.right || event.y > rect.bottom) {
graffitis.value.splice(graffitis.value.length - 1, 1);
nowGraffiti.value = -1;
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = true;
initialMouseX = event.clientX;
initialMouseY = event.clientY;
initialDocumentX = dragDocument.offsetLeft;
initialDocumentY = dragDocument.offsetTop;
dragDocument.style.cursor = 'grabbing';
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
setMouseData();
nowGraffiti.value = graffitis.value.length - 1;
}
window.removeEventListener('mousemove', onMouseMoveGraffit);
window.removeEventListener('mouseup', onMouseUpGraffit);
}
//
// -
function onMouseMove(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
//
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
setMouseData();
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
if (isDragging.value) {
const deltaX = event.clientX - initialMouseX;
const deltaY = event.clientY - initialMouseY;
dragDocument.style.left = initialDocumentX + deltaX + 'px';
dragDocument.style.top = initialDocumentY + deltaY + 'px';
}
//
const dragDocument: any = document.querySelector('.dragModal');
if (isDragging.value) {
const deltaX = event.clientX - initialMouseX;
const deltaY = event.clientY - initialMouseY;
dragDocument.style.left = initialDocumentX + deltaX + 'px';
dragDocument.style.top = initialDocumentY + deltaY + 'px';
}
}
//
// -
function onMouseUp(event) {
if (graffitiFlag.value || graffitis.value.some((item) => item.status != 'success')) {
//
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = event.x - rect.x;
endY = event.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (event.x > rect.right || event.y > rect.bottom) {
graffitis.value.splice(graffitis.value.length - 1, 1);
nowGraffiti.value = -1;
} else {
setMouseData();
nowGraffiti.value = graffitis.value.length - 1;
}
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
} else {
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = false;
//
const dragDocument: any = document.querySelector('.dragModal');
isDragging.value = false;
if (dragDocument) {
dragDocument.style.cursor = 'default';
}
}
@ -947,82 +967,92 @@
//------------------------------------------------------------------------
//
function mouseenter(rect, type) {
if (rect.status != 'edit') {
rect.status = 'mouse';
document.body.style.cursor = 'pointer';
}
if (rect.status == 'edit') {
if (type == 'top' || type == 'bottom') {
document.body.style.cursor = 'ns-resize';
}
if (type == 'left' || type == 'right') {
document.body.style.cursor = 'ew-resize';
}
if (type == 'leftTop' || type == 'rightBottom') {
document.body.style.cursor = 'nwse-resize';
if (graffitiFlag.value) {
//
if (rect.status != 'edit') {
rect.status = 'mouse';
document.body.style.cursor = 'pointer';
}
if (type == 'leftBottom' || type == 'rightTop') {
document.body.style.cursor = 'nesw-resize';
//
if (rect.status == 'edit') {
if (type == 'top' || type == 'bottom') {
document.body.style.cursor = 'ns-resize';
}
if (type == 'left' || type == 'right') {
document.body.style.cursor = 'ew-resize';
}
if (type == 'leftTop' || type == 'rightBottom') {
document.body.style.cursor = 'nwse-resize';
}
if (type == 'leftBottom' || type == 'rightTop') {
document.body.style.cursor = 'nesw-resize';
}
}
}
}
//
function mouseleave(rect) {
if (rect.status == 'mouse' || rect.status == 'edit') {
if (rect.status == 'mouse') {
rect.status = 'success';
}
if (graffitiFlag.value) {
document.body.style.cursor = 'crosshair';
} else {
document.body.style.cursor = 'pointer';
if (graffitiFlag.value) {
if (rect.status == 'mouse' || rect.status == 'edit') {
if (rect.status == 'mouse') {
rect.status = 'success';
}
if (rect.status == 'edit') {
document.body.style.cursor = 'crosshair';
}
}
}
}
//
const mouseEditType = ref('');
function funMouseDownEdit(e, index, type) {
//
// graffitisClone.value = cloneDeep(graffitis.value);
// const rect = mouseCanvasRef.value.getBoundingClientRect();
// startX = e.x - rect.x;
// startY = e.y - rect.y;
// isDragging.value = true;
// nowGraffiti.value = index;
// mouseEditType.value = type;
// window.addEventListener('mousemove', funMouseMoveEdit);
// window.addEventListener('mouseup', funMouseUpEdit);
if (graffitiFlag.value) {
//
graffitisClone.value = cloneDeep(graffitis.value);
const rect = mouseCanvasRef.value.getBoundingClientRect();
startX = e.x - rect.x;
startY = e.y - rect.y;
isDragging.value = true;
nowGraffiti.value = index;
mouseEditType.value = type;
window.addEventListener('mousemove', funMouseMoveEdit);
window.addEventListener('mouseup', funMouseUpEdit);
}
}
//
function funMouseMoveEdit(e) {
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
if (graffitiFlag.value) {
const rect = mouseCanvasRef.value.getBoundingClientRect();
if (!isDragging.value) return;
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
funSetMouseDataEdit();
}
funSetMouseDataEdit();
}
//
function funMouseUpEdit(e) {
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (e.x > rect.right || e.y > rect.bottom) {
graffitis.value[nowGraffiti.value] = graffitisClone.value[nowGraffiti.value];
} else {
funSetMouseDataEdit();
if (graffitiFlag.value) {
if (!isDragging.value) return;
const rect = mouseCanvasRef.value.getBoundingClientRect();
endX = e.x - rect.x;
endY = e.y - rect.y;
if (endX < 0 && endY < 0) {
endX = startX;
endY = startY;
}
isDragging.value = false;
if (e.x > rect.right || e.y > rect.bottom) {
graffitis.value[nowGraffiti.value] = graffitisClone.value[nowGraffiti.value];
} else {
funSetMouseDataEdit();
}
window.removeEventListener('mousemove', funMouseMoveEdit);
window.removeEventListener('mouseup', funMouseUpEdit);
}
window.removeEventListener('mousemove', funMouseMoveEdit);
window.removeEventListener('mouseup', funMouseUpEdit);
}
//
function funSetMouseDataEdit() {

@ -65,7 +65,7 @@
<span class="infotitle">拍摄负载</span>
</a-col>
<a-col :span="17">
<span class="infovalue">{{ props.nowPreviewRecord.photographNumber }} </span>
<span class="infovalue">{{ props.nowPreviewRecord.payloadName }} </span>
</a-col>
<a-col :span="7">
<span class="infotitle">拍摄人员</span>
@ -189,17 +189,22 @@
</a-col>
<a-col :span="17">
<span class="infobutton">
<EnvironmentOutlined
v-if="props.nowPreviewRecord.showOnMap == 1"
style="font-size: 20px; color: #07aaed"
@click="flyPoint"
/>
<a-tooltip placement="top">
<template #title>
<div>查看地图图片历史路径</div>
<div>只展示在地图上加载的图片</div>
</template>
<EnvironmentOutlined
v-if="props.nowPreviewRecord.showOnMap == 1"
style="font-size: 20px; color: #07aaed"
@click="openPathModal"
/>
</a-tooltip>
</span>
</a-col>
<a-col :span="24">
<div class="map">
<Map
ref="mapRef"
:nowPreviewRecord="props.nowPreviewRecord"
:previewRecordList="props.previewRecordList"
@chooseNowPreviewRecord="chooseNowPreviewRecord"
@ -220,18 +225,13 @@
CheckOutlined,
CloseOutlined,
} from '@ant-design/icons-vue';
import {
UpdatePicStatus,
Deletepic,
UpdatePicName,
UpdatePicParentKey,
} from '@/api/demo/mediaLibrary';
import { UpdatePicStatus, UpdatePicName } from '@/api/demo/mediaLibrary';
import { Map } from './preview';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const props = defineProps(['nowPreviewRecord', 'previewRecordList', 'hideOrShowTextboxFlag']);
const emits = defineEmits(['chooseNowPreviewRecord', 'handleSuccess']);
const emits = defineEmits(['chooseNowPreviewRecord', 'handleSuccess', 'openPathModal']);
// --------------------------------
const editNameFlag = ref(true);
@ -299,9 +299,12 @@
id: props.nowPreviewRecord.id,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: JSON.stringify(graffitiJson.value),
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
addFileTagsFlag.value = true;
newFileTagsName.value = '';
createMessage.success('添加标签成功');
emits('handleSuccess');
});
} else {
@ -326,7 +329,10 @@
id: props.nowPreviewRecord.id,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: JSON.stringify(graffitiJson.value),
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
createMessage.success('删除标签成功');
emits('handleSuccess');
});
},
@ -359,10 +365,9 @@
emits('chooseNowPreviewRecord', value);
}
// --------------------------------
const mapRef = ref();
function flyPoint() {
mapRef.value?.flyToPoint([props.nowPreviewRecord.lng, props.nowPreviewRecord.lat]);
//
function openPathModal() {
emits('openPathModal', props.nowPreviewRecord);
}
</script>
<style lang="less" scoped>

@ -1,7 +1,13 @@
<template>
<div class="videoDiv">
<div class="showVideo">
<video :src="props.nowPreviewRecord.url" class="video-player" controls muted autoplay></video>
<video
:src="`${VITE_MEDIALIBRARY_IMAGE_URL + props.nowPreviewRecord.objectKey}`"
class="video-player"
controls
muted
autoplay
></video>
</div>
<div class="bottomDiv">
@ -12,7 +18,7 @@
<template #title>
<span>下载</span>
</template>
<DownloadOutlined @click="fetchAndDownloadVideo(props.nowPreviewRecord.url)" />
<DownloadOutlined @click="fetchAndDownloadVideo(props.nowPreviewRecord.objectKey)" />
</a-tooltip>
</div>
<!-- 删除 -->
@ -28,8 +34,8 @@
<div class="imageList">
<div v-for="li in props.previewRecordList" :key="li.id" @click="chooseNowPreviewRecord(li)">
<div
v-if="li.objectKey"
:class="li.id == props.nowPreviewRecord.id ? 'bottom_div_choose' : 'bottom_div'"
v-if="li.type == 'video'"
>
<img :src="li.gifZoomImage" :width="60" :height="40" />
</div>
@ -53,13 +59,20 @@
LeftOutlined,
RightOutlined,
} from '@ant-design/icons-vue';
import { Deletepic } from '@/api/demo/mediaLibrary';
import { getAppEnvConfig } from '@/utils/env';
import { useMessage } from '@/hooks/web/useMessage';
const { VITE_MEDIALIBRARY_IMAGE_URL } = getAppEnvConfig();
const { createConfirm, createMessage } = useMessage();
const props = defineProps(['nowPreviewRecord', 'previewRecordList']);
const emit = defineEmits(['chooseNowPreviewRecord', 'reloadTable']);
const emits = defineEmits(['chooseNowPreviewRecord', 'handleSuccess']);
//
//
function clickLeftOrRightButton(direction) {
const list = props.previewRecordList.filter((item) => item.type == 'video');
const list = props.previewRecordList.filter(
(item) => item.objectKey && item.objectKey.includes('mp4'),
);
for (let index = 0; index < list.length; index++) {
if (list[index].id == props.nowPreviewRecord.id) {
if (direction == 'left') {
@ -82,7 +95,7 @@
//
async function fetchAndDownloadVideo(url) {
try {
const response = await fetch(url, {
const response = await fetch(VITE_MEDIALIBRARY_IMAGE_URL + url, {
mode: 'cors',
});
if (!response.ok) {
@ -92,7 +105,7 @@
const urlObject = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = urlObject;
link.download = props.nowPreviewRecord.name;
link.download = props.nowPreviewRecord.name || 'download';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
@ -102,10 +115,34 @@
}
}
//
function deleteVideo() {}
function deleteVideo() {
let content = '确定要删除选择的文件吗?';
if (props.previewRecordList.length == 1) {
content = '下列视频只有一个,删除此视频后将会关闭此弹窗,确定要删除选择的文件吗?';
}
createConfirm({
iconType: 'info',
title: '删除',
content: content,
onOk: async () => {
let ids = props.nowPreviewRecord.id;
Deletepic({
ids: ids,
}).then((res) => {
handleSuccess(props.nowPreviewRecord);
createMessage.success(res);
});
},
});
}
//
function handleSuccess(record = null) {
emits('handleSuccess', record);
}
//
function chooseNowPreviewRecord(value) {
emit('chooseNowPreviewRecord', value);
emits('chooseNowPreviewRecord', value);
}
</script>
<style lang="less" scoped>

@ -12,7 +12,7 @@
<EditOutlined style="font-size: 20px; color: #07aaed" @click="editNameChange" />
</span>
<span class="infovalue_name" v-if="!editNameFlag">
<a-input v-model:value="editName" size="small" style="width: 80%" />
<a-input v-model:value="editName" size="small" />
<CheckOutlined
style="margin-left: 10px; color: green"
@click="pressEnterNameFunction"
@ -99,14 +99,17 @@
</a-col>
<a-col :span="17">
<span class="infovalue_graffitiNum">
<a-tag color="success" v-for="la in props.nowPreviewRecord.label" :key="la">
<a-tag color="success" v-for="la in props.nowPreviewRecord.fileTags" :key="la">
{{ la }}
</a-tag>
<PlusSquareOutlined style="font-size: 20px; color: #07aaed" @click="addLabelChange" />
<PlusSquareOutlined
style="font-size: 20px; color: #07aaed"
@click="addFileTagsChange"
/>
</span>
<a-modal
title="标签设置"
:open="addLabelFlag"
:open="addFileTagsFlag"
:mask="false"
:maskClosable="false"
:closable="false"
@ -115,24 +118,24 @@
<div style="display: block">
<div
style="display: flex; flex-wrap: wrap; gap: 5px; width: 96%; margin: 10px"
v-if="props.nowPreviewRecord.label && props.nowPreviewRecord.label.length > 0"
v-if="props.nowPreviewRecord.fileTags.length > 0"
>
已添加的标签
<div
v-for="la in props.nowPreviewRecord.label"
v-for="la in props.nowPreviewRecord.fileTags"
:key="la"
style="border: 1px solid #595959; border-radius: 3px"
>
<span style="margin-left: 5px">{{ la }}</span>
<CloseOutlined
style="margin-left: 5px; margin-right: 5px"
@click="deleteLabel(la)"
@click="deleteFileTags(la)"
/>
</div>
</div>
<div style="display: inline-flex; gap: 5px; width: 96%; margin: 10px">
<a-input v-model:value="newLabelName" size="small" placeholder="请输入标签" />
<a-button type="primary" @click="pressEnterLabelFunction"></a-button>
<a-input v-model:value="newFileTagsName" size="small" placeholder="请输入标签" />
<a-button type="primary" @click="pressEnterFileTagsFunction"></a-button>
</div>
<div
style="
@ -145,8 +148,8 @@
>
<a-button
@click="
addLabelFlag = false;
newLabelName = '';
addFileTagsFlag = false;
newFileTagsName = '';
"
>
关闭
@ -160,21 +163,19 @@
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { ref, watch, computed } from 'vue';
import {
EditOutlined,
PlusSquareOutlined,
EnvironmentOutlined,
CheckOutlined,
CloseOutlined,
} from '@ant-design/icons-vue';
import { orgPosGroup } from '@/api/demo/system';
import { Map } from './preview';
import { UpdatePicName, UpdatePicStatus } from '@/api/demo/mediaLibrary';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage, createConfirm } = useMessage();
const { createMessage } = useMessage();
const props = defineProps(['nowPreviewRecord', 'previewRecordList', 'hideOrShowTextboxFlag']);
const emit = defineEmits(['chooseNowPreviewRecord', 'reloadTable']);
const props = defineProps(['nowPreviewRecord', 'previewRecordList']);
const emits = defineEmits(['chooseNowPreviewRecord', 'handleSuccess']);
// --------------------------------
const editNameFlag = ref(true);
@ -195,21 +196,14 @@
}
let query = {
id: props.nowPreviewRecord.id,
newName: newName,
name: newName,
};
props.nowPreviewRecord.name = newName;
editNameFlag.value = true;
emit('reloadTable');
return;
//
const data = await orgPosGroup(query);
if (data) {
UpdatePicName(query).then((res) => {
props.nowPreviewRecord.name = newName;
editNameFlag.value = true;
emit('reloadTable');
return createMessage.success('修改名称成功');
} else {
return createMessage.error('修改名称失败');
}
createMessage.success(res);
emits('handleSuccess');
});
}
function editNameBlur() {
editNameFlag.value = true;
@ -217,64 +211,66 @@
}
// --------------------------------
const addLabelFlag = ref(false);
const newLabelName = ref('');
function addLabelChange() {
addLabelFlag.value = true;
const addFileTagsFlag = ref(false);
const newFileTagsName = ref('');
const fileTags: any = ref([]);
watch(
() => props.nowPreviewRecord,
() => {
fileTags.value = props.nowPreviewRecord.fileTags ? props.nowPreviewRecord.fileTags : [];
},
{
deep: true,
immediate: true,
},
);
//
function addFileTagsChange() {
addFileTagsFlag.value = true;
}
//
async function pressEnterLabelFunction() {
if (!newLabelName.value) {
async function pressEnterFileTagsFunction() {
if (!newFileTagsName.value) {
return;
}
if (
!props.nowPreviewRecord.label ||
!props.nowPreviewRecord.label.includes(newLabelName.value)
) {
if (!props.nowPreviewRecord.label) {
props.nowPreviewRecord.label = [];
}
props.nowPreviewRecord.label.push(newLabelName.value);
let query = {
if (!fileTags.value.includes(newFileTagsName.value)) {
fileTags.value.push(newFileTagsName.value);
UpdatePicStatus({
id: props.nowPreviewRecord.id,
newLabel: props.nowPreviewRecord.label,
};
addLabelFlag.value = true;
chooseNowPreviewRecord({
...props.nowPreviewRecord,
label: props.nowPreviewRecord.label,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: props.nowPreviewRecord.graffitiJson,
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
addFileTagsFlag.value = true;
newFileTagsName.value = '';
createMessage.success('添加标签成功');
emits('handleSuccess');
});
emit('reloadTable');
newLabelName.value = '';
return;
//
const data = await orgPosGroup(query);
if (data) {
addLabelFlag.value = true;
emit('reloadTable');
return createMessage.success('修改名称成功');
} else {
return createMessage.error('修改名称失败');
}
} else {
return createMessage.error('此标签已存在!');
}
}
//
function deleteLabel(value) {
props.nowPreviewRecord.label = props.nowPreviewRecord.label.filter((item) => item !== value);
chooseNowPreviewRecord({
...props.nowPreviewRecord,
label: props.nowPreviewRecord.label,
function deleteFileTags(value) {
fileTags.value = fileTags.value.filter((item) => item !== value);
UpdatePicStatus({
id: props.nowPreviewRecord.id,
fileTags: JSON.stringify(fileTags.value),
graffitiJson: props.nowPreviewRecord.graffitiJson,
display: props.nowPreviewRecord.display,
showOnMap: props.nowPreviewRecord.showOnMap,
}).then((res) => {
createMessage.success('删除标签成功');
emits('handleSuccess');
});
emit('reloadTable');
}
//
function chooseNowPreviewRecord(value) {
emit('chooseNowPreviewRecord', value);
emits('chooseNowPreviewRecord', value);
}
</script>
<style lang="less" scoped>

@ -65,19 +65,19 @@
}
function treeIterator(tree) {
tree.forEach((node) => {
node.name = node.item.name;
node.id = node.item.id;
node.elements = node.item.elements;
node.name = node.name;
node.id = node.id;
node.elements = node.elements;
node.children && treeIterator(node.children);
});
}
function btnIterator(moduleId, tree) {
tree.forEach((node) => {
if (moduleId == node.item.id) {
if (moduleId == node.id) {
btnData.value.push({
name: node.item.name,
id: node.item.id,
elements: node.item.elements,
name: node.name,
id: node.id,
elements: node.elements,
disabled: true,
});
}

@ -26,7 +26,7 @@ export const columns = [
},
{
title: '加入组织时间',
dataIndex: 'updateTime',
dataIndex: 'createTime',
},
];

@ -81,9 +81,16 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 4 },
},
{
field: 'model',
field: 'type',
label: '设备型号',
component: 'Input',
component: 'Select',
componentProps: {
options: [
{ label: 'Dock 1', value: 'Dock 1' },
{ label: 'Dock 2', value: 'Dock 2' },
{ label: 'Dock 3', value: 'Dock 3' },
],
},
colProps: { span: 4 },
},
{

@ -477,7 +477,48 @@
};
servicesTopic(querys);
};
const handleKeyDown = (event) => {
if (event.key === 'w') {
changeDRC('throttle', 'up', '上升');
} else if (event.key === 's') {
changeDRC('throttle', 'down', '下降');
} else if (event.key === 'a') {
changeDRC('yaw', 'down', '左旋转');
} else if (event.key === 'd') {
changeDRC('yaw', 'up', '右旋转');
} else if (event.key === 'ArrowUp') {
changeDRC('pitch', 'up', '前进');
} else if (event.key === 'ArrowDown') {
changeDRC('pitch', 'down', '后退');
} else if (event.key === 'ArrowLeft') {
changeDRC('roll', 'down', '左移');
} else if (event.key === 'ArrowRight') {
changeDRC('roll', 'up', '右移');
}
};
const handleKeyUp = (event) => {
if (event.key === 'w') {
changeDRC('throttle', 'up', '');
} else if (event.key === 's') {
changeDRC('throttle', 'down', '');
} else if (event.key === 'd') {
changeDRC('yaw', 'down', '');
} else if (event.key === 'a') {
changeDRC('yaw', 'up', '');
} else if (event.key === 'ArrowUp') {
changeDRC('pitch', 'up', '');
} else if (event.key === 'ArrowDown') {
changeDRC('pitch', 'down', '');
} else if (event.key === 'ArrowLeft') {
changeDRC('roll', 'down', '');
} else if (event.key === 'ArrowRight') {
changeDRC('roll', 'up', '');
}
};
onMounted(() => {
//
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
// mqtt
getRedisUser(userInfo.id).then((res) => {
if (res) {
@ -570,6 +611,8 @@
destroySeizeConnection();
changeRedisUser(false);
monitorDRC.value = false;
document.removeEventListener('keydown', handleKeyDown);
document.removeEventListener('keyup', handleKeyUp);
});
</script>
<style lang="less" scoped>

@ -14,16 +14,12 @@
{{ time }}
<!-- <span>临近或已接近夜晚</span> -->
</div>
<div class="content-item">
<!-- <div class="content-item">
<div class="item-div" title="飞行器上 Dongle 数量">
<img src="@/assets/images/flightoperation/project.png" alt="" />
{{ uavInformation.wireless_link ? uavInformation.wireless_link.dongle_number : 0 }}
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<!-- <div class="item-div">
<img src="@/assets/images/flightoperation/arrow.png" alt="" />
0%
</div> -->
<div class="item-div" title="电量百分比">
<img src="@/assets/images/flightoperation/electricity.png" alt="" />
{{
@ -32,16 +28,17 @@
: 0
}}
</div>
</div>
</div> -->
<div class="content-item">
<div class="item-div" title="SDR 链路连接状态">
<img src="@/assets/images/flightoperation/sdr.png" alt="" />
<!-- sdr_link_state -->
<template
v-if="uavInformation.wireless_link && uavInformation.wireless_link.sdr_link_state == 1"
>连接</template
>
<template v-else></template>
连接</template
>
<template v-else> </template>
</div>
<a-divider type="vertical" style="border-color: #4e5778" />
<div class="item-div" title="4G 链路连接状态">
@ -50,9 +47,10 @@
v-if="
uavInformation.wireless_link && uavInformation.wireless_link['4g_link_state'] == 1
"
>连接</template
>
<template v-else></template>
连接</template
>
<template v-else> </template>
</div>
</div>
<!-- sdr_freq_band sdr_quality 4g_freq_band 4g_quality -->

@ -190,7 +190,7 @@
</div>
<div class="footer-container">
<div >
<a-button @click="resetForm" style="width:100%;">取消</a-button>
<a-button v-if="!paramValue" @click="resetForm" style="width:100%;"></a-button>
</div>
<div v-if="submitForm.status == 0">
<a-button style="width:100%;" type="primary" @click="onSubmit"></a-button>
@ -204,6 +204,9 @@ import { ref, defineEmits, defineProps, watch } from "vue";
import { PlusOutlined,LeftOutlined,DeleteOutlined,MoreOutlined } from '@ant-design/icons-vue';
import { addTask,editTask } from "@/api/sys/workplan";
import { Modal, message } from 'ant-design-vue';
import { useRoute } from 'vue-router'
const router = useRoute()
const paramValue = router.query.taskid
const formRef = ref();
const labelCol = { span: 24 };
@ -245,7 +248,8 @@ const props = defineProps({
"expectedFileCount": 0,
"uploadedFileCount": 0,
"flightId": null,
"reason": null
"reason": null,
"externalTaskId": null
})
},
"editMode":{
@ -256,8 +260,6 @@ const props = defineProps({
const weekdays = ref([
{
'label':'周日',
@ -369,7 +371,8 @@ const submitForm = ref({
"expectedFileCount": 0,
"uploadedFileCount": 0,
"flightId": null,
"reason": null
"reason": null,
"externalTaskId": null
})
@ -510,6 +513,9 @@ const onSubmit =async () => {
message.error("操作失败!");
}
}else{
if(paramValue){
submitForm.value.externalTaskId = paramValue
}
//
let res = await addTask(submitForm.value);
if(res){

@ -72,6 +72,11 @@ import axios from 'axios';
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
import { useRoute } from 'vue-router'
const router = useRoute()
const paramValue = router.query.taskid
const airLineForm = ref({
"id": null,
"airLineName": null,
@ -112,6 +117,10 @@ const aircraftShow = ref(false);
const createAirLineShow = ref(false);
const importAirLineShow = ref(true);
if(paramValue){
planListShow.value = false;
workPlanFormShow.value = true;
}
const selectAriLine = ()=> {
ariLineShow.value = true;
aircraftShow.value = false;

Loading…
Cancel
Save