Merge branch 'xhf' of http://git.znkjfw.com/ak/zn-admin-vue3-wcs into xhf
BIN
src/assets/imgs/indexPage/yanjing_xianshi_o.png
Normal file
After Width: | Height: | Size: 554 B |
BIN
src/assets/imgs/indexPage/yanjing_yincang_o.png
Normal file
After Width: | Height: | Size: 732 B |
BIN
src/assets/imgs/indexPage/zhankai@2x.png
Normal file
After Width: | Height: | Size: 419 B |
BIN
src/assets/imgs/indexPage/编组 12.png
Normal file
After Width: | Height: | Size: 855 B |
BIN
src/assets/imgs/indexPage/编组 14.png
Normal file
After Width: | Height: | Size: 856 B |
BIN
src/assets/imgs/indexPage/编组 15.png
Normal file
After Width: | Height: | Size: 794 B |
BIN
src/assets/imgs/indexPage/编组 22.png
Normal file
After Width: | Height: | Size: 666 B |
@ -2,7 +2,7 @@
|
|||||||
export const vDrag = {
|
export const vDrag = {
|
||||||
mounted(el, binding) {
|
mounted(el, binding) {
|
||||||
const enableDrag = binding.value; // 获取指令绑定的值
|
const enableDrag = binding.value; // 获取指令绑定的值
|
||||||
if (!enableDrag) return; // 如果为 false,则不执行后续拖拽逻辑
|
// if (!enableDrag) return; // 如果为 false,则不执行后续拖拽逻辑
|
||||||
el.style.position = 'absolute';
|
el.style.position = 'absolute';
|
||||||
|
|
||||||
// 记录元素的初始位置
|
// 记录元素的初始位置
|
||||||
@ -39,8 +39,16 @@ export const vDrag = {
|
|||||||
// 保存初始位置,以便后续还原
|
// 保存初始位置,以便后续还原
|
||||||
el.__vDragInitialTop = initialTop;
|
el.__vDragInitialTop = initialTop;
|
||||||
el.__vDragInitialLeft = initialLeft;
|
el.__vDragInitialLeft = initialLeft;
|
||||||
|
if(!enableDrag){
|
||||||
|
// 如果之前启用,现在禁用,移除 mousedown 事件监听器
|
||||||
|
el.removeEventListener('mousedown', el.__vDragMousedown);
|
||||||
|
// 确保在禁用时停止正在进行的拖拽
|
||||||
|
document.removeEventListener('mousemove', el.__vDragMousemove);
|
||||||
|
document.removeEventListener('mouseup', el.__vDragMouseup);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updated(el, binding) {
|
updated(el, binding) {
|
||||||
|
console.log('会走这边吗');
|
||||||
const enableDrag = binding.value;
|
const enableDrag = binding.value;
|
||||||
const prevEnableDrag = binding.oldValue;
|
const prevEnableDrag = binding.oldValue;
|
||||||
|
|
||||||
@ -65,6 +73,7 @@ export const vDrag = {
|
|||||||
|
|
||||||
// 定义一个还原位置的函数
|
// 定义一个还原位置的函数
|
||||||
export const resetDragPosition = (el) => {
|
export const resetDragPosition = (el) => {
|
||||||
|
console.log(el);
|
||||||
if (el.__vDragInitialTop!== undefined && el.__vDragInitialLeft!== undefined) {
|
if (el.__vDragInitialTop!== undefined && el.__vDragInitialLeft!== undefined) {
|
||||||
el.style.top = `${el.__vDragInitialTop}px`;
|
el.style.top = `${el.__vDragInitialTop}px`;
|
||||||
el.style.left = `${el.__vDragInitialLeft}px`;
|
el.style.left = `${el.__vDragInitialLeft}px`;
|
||||||
|
@ -1,35 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="affix-container" :style="{ height: (heightVal*radio ) + 'px'}">
|
<div
|
||||||
<!-- <el-affix target=".affix-container" :offset="80">
|
class="affix-container"
|
||||||
<span @click="resetPosition ">回到原点</span>
|
id="indexpage-container"
|
||||||
<div class="affix-container-top">
|
:style="{ height: heightVal * radio + 'px',cursor:isDrag ? 'pointer' : 'default',scale:isSizeRaio,transformOrigin: 'center center' }"
|
||||||
<el-scrollbar>
|
>
|
||||||
<div class="scrollbar-flex-content">
|
|
||||||
<el-dropdown
|
<div
|
||||||
placement="bottom"
|
class="indexpage-container"
|
||||||
v-for="(item, index) in list"
|
v-if="imgUrl"
|
||||||
:key="index"
|
v-drag="isDrag"
|
||||||
style="border: none"
|
:style="{ scale: 1, transformOrigin: '0 0' }"
|
||||||
>
|
ref="draggableElement"
|
||||||
<div class="scrollbar-demo-item">
|
>
|
||||||
{{ item.floor }}
|
|
||||||
</div>
|
|
||||||
<template #dropdown v-if="item.children && item.children.length">
|
|
||||||
<el-dropdown-menu style="width: 100px">
|
|
||||||
<el-dropdown-item
|
|
||||||
v-for="(p, i) in item.children"
|
|
||||||
:key="i"
|
|
||||||
@click="getMapData(p)"
|
|
||||||
>{{ p.area }}</el-dropdown-item
|
|
||||||
>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
</el-affix> -->
|
|
||||||
<div class="indexpage-container" v-if="imgUrl" v-drag="true" :style="{scale:1,transformOrigin:'0 0'}" ref="draggableElement">
|
|
||||||
<div class="indexpage-container-box">
|
<div class="indexpage-container-box">
|
||||||
<img :src="imgUrl" alt="" class="indexpage-container-box-img" />
|
<img :src="imgUrl" alt="" class="indexpage-container-box-img" />
|
||||||
|
|
||||||
@ -51,17 +33,23 @@
|
|||||||
>
|
>
|
||||||
</div> -->
|
</div> -->
|
||||||
<!-- 小车 -->
|
<!-- 小车 -->
|
||||||
<div class="indexpage-car-item"
|
<div
|
||||||
v-for="(item, index) in testCarList"
|
class="indexpage-car-item"
|
||||||
@dblclick="carDbClick(item,index)"
|
v-for="(item, index) in testCarList"
|
||||||
:key="index"
|
@dblclick="carDbClick(item, index)"
|
||||||
:style="{
|
:key="index"
|
||||||
|
:style="{
|
||||||
left: item.realX * radio + 'px',
|
left: item.realX * radio + 'px',
|
||||||
top: item.realY * radio + 'px',
|
top: item.realY * radio + 'px',
|
||||||
width: 40 * radio + 'px',
|
width: 40 * radio + 'px',
|
||||||
height: 22 * radio + 'px',
|
height: 22 * radio + 'px'
|
||||||
}">
|
}"
|
||||||
<img src="@/assets/imgs/indexPage/chache-4备份 7@2x.png" alt="" style="width: 100%; height: 100%" />
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/imgs/indexPage/chache-4备份 7@2x.png"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="indexpage-container-box-point-item"
|
class="indexpage-container-box-point-item"
|
||||||
@ -135,20 +123,84 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 左下角图例 -->
|
||||||
|
<div class="affix-container-left" :style="{ left: boxLeft + 'px' }">
|
||||||
|
<div class="affix-container-left-box">
|
||||||
|
<div class="affix-container-left-box-item-box" :style="{ height: legendObj.legendShow ? '84px' : '0', overflow: 'hidden',transition: 'all 0.3s ease-in-out'}">
|
||||||
|
<div class="affix-container-left-box-item">
|
||||||
|
<div class="affix-container-left-box-item-left"> 行驶路线 </div>
|
||||||
|
<img
|
||||||
|
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
||||||
|
alt=""
|
||||||
|
class="affix-container-left-box-item-img"
|
||||||
|
v-if="legendObj.driveLineShow"
|
||||||
|
@click="changDriveLineShow"
|
||||||
|
/>
|
||||||
|
<img src="@/assets/imgs/indexPage/yanjing_yincang_o.png" alt="" class="affix-container-left-box-item-img" v-if="!legendObj.driveLineShow" @click="changDriveLineShow"/>
|
||||||
|
</div>
|
||||||
|
<div class="affix-container-left-box-item">
|
||||||
|
<div class="affix-container-left-box-item-left"> 车辆 </div>
|
||||||
|
<img
|
||||||
|
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
||||||
|
alt=""
|
||||||
|
class="affix-container-left-box-item-img"
|
||||||
|
v-if="legendObj.carShow"
|
||||||
|
@click="changCarShow"
|
||||||
|
/>
|
||||||
|
<img src="@/assets/imgs/indexPage/yanjing_yincang_o.png" alt="" class="affix-container-left-box-item-img" v-if="!legendObj.carShow" @click="changCarShow"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="affix-container-left-box-item-bottom" @click="legendObj.legendShow = !legendObj.legendShow">
|
||||||
|
<div class="affix-container-left-box-item-bottom-left">
|
||||||
|
图例
|
||||||
|
</div>
|
||||||
|
<img src="@/assets/imgs/indexPage/zhankai@2x.png" alt="" class="affix-container-left-box-item-bottom-img" :style="{transform: legendObj.legendShow ? 'rotate(180deg)' : 'rotate(0deg)',transition: 'all 0.3s ease-in-out'}"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右下角的功能 -->
|
||||||
|
<div class="affix-container-right">
|
||||||
|
<!-- 拖拽 -->
|
||||||
|
<div class="affix-container-right-item" @click="changeIsDrag">
|
||||||
|
<img src="@/assets/imgs/indexPage/编组 12.png" alt="" style="width: 100%;height: 100%;" />
|
||||||
|
</div>
|
||||||
|
<!-- 放大 -->
|
||||||
|
<div class="affix-container-right-item">
|
||||||
|
<img src="@/assets/imgs/indexPage/编组 14.png" alt="" style="width: 100%;height: 100%;" @click="changeSizeRaio(0.2)"/>
|
||||||
|
</div>
|
||||||
|
<!-- 缩小 -->
|
||||||
|
<div class="affix-container-right-item">
|
||||||
|
<img src="@/assets/imgs/indexPage/编组 15.png" alt="" style="width: 100%;height: 100%;" @click="changeSizeRaio(-0.2)"/>
|
||||||
|
</div>
|
||||||
|
<!-- 全屏 -->
|
||||||
|
<div class="affix-container-right-item">
|
||||||
|
<img src="@/assets/imgs/indexPage/编组 22.png" alt="" style="width: 100%;height: 100%;" @click="toggleFullScreen" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<storeDialog ref="storeDialogRef" @success="getList" />
|
<storeDialog ref="storeDialogRef" @success="getList" />
|
||||||
<carDialog ref="carDialogRef" />
|
<carDialog ref="carDialogRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineComponent, reactive, nextTick, onMounted, onBeforeUnmount } from 'vue'
|
import {
|
||||||
|
ref,
|
||||||
|
defineComponent,
|
||||||
|
reactive,
|
||||||
|
nextTick,
|
||||||
|
onMounted,
|
||||||
|
onBeforeUnmount,
|
||||||
|
onUnmounted,
|
||||||
|
} from 'vue'
|
||||||
import * as MapApi from '@/api/map/map'
|
import * as MapApi from '@/api/map/map'
|
||||||
import WebSocketClient from '../webSocket.js'
|
import WebSocketClient from '../webSocket.js'
|
||||||
import storeDialog from './storeDialog.vue'
|
import storeDialog from './storeDialog.vue'
|
||||||
import { color } from 'echarts'
|
import { color } from 'echarts'
|
||||||
import { resetDragPosition } from '@/utils/drag'
|
import { resetDragPosition } from '@/utils/drag'
|
||||||
import carDialog from './carDialog.vue'
|
import carDialog from './carDialog.vue'
|
||||||
|
import { is } from 'bpmn-js/lib/util/ModelUtil'
|
||||||
const imgUrl = ref('')
|
const imgUrl = ref('')
|
||||||
const carDialogRef = ref(null)
|
const carDialogRef = ref(null)
|
||||||
const socketClient = ref(null)
|
const socketClient = ref(null)
|
||||||
|
|
||||||
const emit = defineEmits(['transmitMapId'])
|
const emit = defineEmits(['transmitMapId'])
|
||||||
@ -157,7 +209,11 @@ const list = ref([])
|
|||||||
const nowObject = ref(null)
|
const nowObject = ref(null)
|
||||||
const testCarList = ref([])
|
const testCarList = ref([])
|
||||||
const carPointListFun = () => {
|
const carPointListFun = () => {
|
||||||
let testJson = {"type":"map_push","content":"{\"d0:65:78:c4:af:cc\":\"{\\\"id\\\":1,\\\"macAddress\\\":\\\"d0:65:78:c4:af:cc\\\",\\\"robotModelNumber\\\":\\\"A-1\\\",\\\"pose2d\\\":{\\\"y\\\":\\\"1\\\",\\\"x\\\":\\\"2\\\",\\\"yaw\\\":\\\"30\\\",\\\"floor\\\":\\\"1\\\",\\\"area\\\":\\\"A区\\\",\\\"bat_soc\\\":\\\"40\\\"}}\"}"}
|
let testJson = {
|
||||||
|
type: 'map_push',
|
||||||
|
content:
|
||||||
|
'{"d0:65:78:c4:af:cc":"{\\"id\\":1,\\"macAddress\\":\\"d0:65:78:c4:af:cc\\",\\"robotModelNumber\\":\\"A-1\\",\\"pose2d\\":{\\"y\\":\\"1\\",\\"x\\":\\"2\\",\\"yaw\\":\\"30\\",\\"floor\\":\\"1\\",\\"area\\":\\"A区\\",\\"bat_soc\\":\\"40\\"}}"}'
|
||||||
|
}
|
||||||
let data = JSON.parse(testJson.content)
|
let data = JSON.parse(testJson.content)
|
||||||
// console.log("============",data)
|
// console.log("============",data)
|
||||||
let dataList = []
|
let dataList = []
|
||||||
@ -167,12 +223,125 @@ const carPointListFun = () => {
|
|||||||
data: JSON.parse(data[key])
|
data: JSON.parse(data[key])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log("=====",dataList)
|
console.log('=====', dataList)
|
||||||
testCarList.value = dataList
|
testCarList.value = dataList
|
||||||
|
|
||||||
// let data2 = JSON.parse(data['d0:65:78:c4:af:cc'])
|
// let data2 = JSON.parse(data['d0:65:78:c4:af:cc'])
|
||||||
// console.log(data2)
|
// console.log(data2)
|
||||||
}
|
}
|
||||||
|
//是否可以拖拽
|
||||||
|
const isDrag = ref(false)
|
||||||
|
const changeIsDrag = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
isDrag.value = !isDrag.value
|
||||||
|
console.log(isDrag.value)
|
||||||
|
if(!isDrag.value){
|
||||||
|
//还原位置
|
||||||
|
resetPosition()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//放大缩小
|
||||||
|
const isSizeRaio = ref(1)
|
||||||
|
const changeSizeRaio = (type) => {
|
||||||
|
if(type<0 && (isSizeRaio.value + type) <= 0){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isSizeRaio.value += type
|
||||||
|
}
|
||||||
|
//图例状态
|
||||||
|
const legendObj = reactive({
|
||||||
|
driveLineShow:false,
|
||||||
|
carShow:false,
|
||||||
|
legendShow:true
|
||||||
|
})
|
||||||
|
// 车辆是否显示
|
||||||
|
const changCarShow = () => {
|
||||||
|
legendObj.carShow = !legendObj.carShow
|
||||||
|
}
|
||||||
|
// 车辆行驶路线是否展示
|
||||||
|
const changDriveLineShow = () => {
|
||||||
|
legendObj.driveLineShow = !legendObj.driveLineShow
|
||||||
|
}
|
||||||
|
const toggleFullScreen = () => {
|
||||||
|
var elem = document.getElementById("indexpage-container"); // 获取元素
|
||||||
|
if (!document.fullscreenElement) { // 检查是否已经是全屏模式
|
||||||
|
if (elem.requestFullscreen) { // 支持requestFullscreen API的标准方式
|
||||||
|
elem.requestFullscreen().catch(err => {
|
||||||
|
alert(`无法进入全屏模式: ${err.message}`); // 处理错误情况
|
||||||
|
});
|
||||||
|
} else if (elem.mozRequestFullScreen) { // 旧版Firefox的API名称(已废弃)
|
||||||
|
elem.mozRequestFullScreen();
|
||||||
|
} else if (elem.webkitRequestFullscreen) { // WebKit/Safari/Chrome的API名称(已废弃)
|
||||||
|
elem.webkitRequestFullscreen();
|
||||||
|
} else if (elem.msRequestFullscreen) { // IE/Edge的API名称(已废弃)
|
||||||
|
elem.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
isDrag.value = true
|
||||||
|
} else { // 退出全屏模式
|
||||||
|
if (document.exitFullscreen) { // 标准API退出全屏模式
|
||||||
|
document.exitFullscreen();
|
||||||
|
} else if (document.mozCancelFullScreen) { // 旧版Firefox的API名称(已废弃)
|
||||||
|
document.mozCancelFullScreen();
|
||||||
|
} else if (document.webkitExitFullscreen) { // WebKit/Safari/Chrome的API名称(已废弃)
|
||||||
|
document.webkitExitFullscreen();
|
||||||
|
} else if (document.msExitFullscreen) { // IE/Edge的API名称(已废弃)
|
||||||
|
document.msExitFullscreen();
|
||||||
|
}
|
||||||
|
console.log('退出全屏')
|
||||||
|
isDrag.value = false
|
||||||
|
resetPosition()
|
||||||
|
}
|
||||||
|
// 监听全屏状态变化事件
|
||||||
|
document.addEventListener('fullscreenchange', function () {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
console.log('已退出全屏模式');
|
||||||
|
// 在这里可以添加退出全屏后的逻辑
|
||||||
|
isDrag.value = false
|
||||||
|
resetPosition()
|
||||||
|
} else {
|
||||||
|
console.log('已进入全屏模式');
|
||||||
|
// 在这里可以添加进入全屏后的逻辑
|
||||||
|
isDrag.value = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听旧版浏览器的全屏状态变化事件
|
||||||
|
document.addEventListener('mozfullscreenchange', function () {
|
||||||
|
if (!document.mozFullScreenElement) {
|
||||||
|
console.log('已退出全屏模式 (Firefox旧版)');
|
||||||
|
isDrag.value = false
|
||||||
|
resetPosition()
|
||||||
|
} else {
|
||||||
|
console.log('已进入全屏模式 (Firefox旧版)');
|
||||||
|
isDrag.value = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('webkitfullscreenchange', function () {
|
||||||
|
if (!document.webkitFullscreenElement) {
|
||||||
|
console.log('已退出全屏模式 (WebKit旧版)');
|
||||||
|
isDrag.value = false
|
||||||
|
resetPosition()
|
||||||
|
} else {
|
||||||
|
console.log('已进入全屏模式 (WebKit旧版)');
|
||||||
|
isDrag.value = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('msfullscreenchange', function () {
|
||||||
|
if (!document.msFullscreenElement) {
|
||||||
|
console.log('已退出全屏模式 (IE/Edge旧版)');
|
||||||
|
isDrag.value = false
|
||||||
|
resetPosition()
|
||||||
|
} else {
|
||||||
|
console.log('已进入全屏模式 (IE/Edge旧版)');
|
||||||
|
isDrag.value = true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
//获取地图区域
|
//获取地图区域
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
let data = await MapApi.getPositionMapGetMap()
|
let data = await MapApi.getPositionMapGetMap()
|
||||||
@ -185,15 +354,15 @@ const getList = async () => {
|
|||||||
children: data[key]
|
children: data[key]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if(mapList.length){
|
if (mapList.length) {
|
||||||
mapList.forEach(item => {
|
mapList.forEach((item) => {
|
||||||
if(item.children.length){
|
if (item.children.length) {
|
||||||
item.children.forEach(child => {
|
item.children.forEach((child) => {
|
||||||
child.label = child.area
|
child.label = child.area
|
||||||
child.value = child.id
|
child.value = child.id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
list.value = mapList
|
list.value = mapList
|
||||||
@ -252,10 +421,10 @@ const getPositionMapListFun = async (positionMapId) => {
|
|||||||
}
|
}
|
||||||
const draggableElement = ref(null)
|
const draggableElement = ref(null)
|
||||||
const resetPosition = () => {
|
const resetPosition = () => {
|
||||||
if (draggableElement.value) {
|
if (draggableElement.value) {
|
||||||
resetDragPosition(draggableElement.value);
|
resetDragPosition(draggableElement.value)
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const calculateDistanceAndAngle = (point1, point2) => {
|
const calculateDistanceAndAngle = (point1, point2) => {
|
||||||
// 计算水平和垂直方向的差值
|
// 计算水平和垂直方向的差值
|
||||||
const dx = point2.left - point1.left
|
const dx = point2.left - point1.left
|
||||||
@ -319,7 +488,7 @@ const disconnect = () => {
|
|||||||
}
|
}
|
||||||
//获取扫描图
|
//获取扫描图
|
||||||
const getMapData = async (item) => {
|
const getMapData = async (item) => {
|
||||||
console.log("============",item)
|
// console.log("============",item)
|
||||||
nowObject.value = JSON.parse(JSON.stringify(item))
|
nowObject.value = JSON.parse(JSON.stringify(item))
|
||||||
let websoketUrl = `${replaceHttpWithWs(import.meta.env.VITE_BASE_URL)}/infra/ws?type=map&floor=${nowObject.value.floor}&area=${nowObject.value.area}`
|
let websoketUrl = `${replaceHttpWithWs(import.meta.env.VITE_BASE_URL)}/infra/ws?type=map&floor=${nowObject.value.floor}&area=${nowObject.value.area}`
|
||||||
console.log(websoketUrl)
|
console.log(websoketUrl)
|
||||||
@ -343,28 +512,33 @@ const radio = ref(1)
|
|||||||
const computedRatio = () => {
|
const computedRatio = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (imgUrl.value) {
|
if (imgUrl.value) {
|
||||||
|
//这段代码之后会删掉 yaml会给原始宽高
|
||||||
//这段代码之后会删掉 yaml会给原始宽高
|
getImageSize(imgUrl.value)
|
||||||
getImageSize(imgUrl.value)
|
.then(({ width, height }) => {
|
||||||
.then(({ width, height }) => {
|
// console.log("原始地图的宽高",JSON.parse(nowObject.value.yamlJson))
|
||||||
// console.log("原始地图的宽高",JSON.parse(nowObject.value.yamlJson))
|
if (testCarList.value.length) {
|
||||||
if(testCarList.value.length){
|
testCarList.value.forEach((item) => {
|
||||||
testCarList.value.forEach((item) => {
|
item.originWidth = width
|
||||||
item.originWidth = width
|
item.originHeight = height
|
||||||
item.originHeight = height
|
item.origin = JSON.parse(nowObject.value.yamlJson).origin
|
||||||
item.origin = JSON.parse(nowObject.value.yamlJson).origin
|
item.realX = convertToFrontendCoordinates(item.origin, width, height, [
|
||||||
item.realX = convertToFrontendCoordinates(item.origin, width, height, [item.data.pose2d.x, item.data.pose2d.y]).left
|
item.data.pose2d.x,
|
||||||
item.realY = convertToFrontendCoordinates(item.origin, width, height, [item.data.pose2d.x, item.data.pose2d.y]).top
|
item.data.pose2d.y
|
||||||
})
|
]).left
|
||||||
console.log("当前数据",testCarList.value)
|
item.realY = convertToFrontendCoordinates(item.origin, width, height, [
|
||||||
}
|
item.data.pose2d.x,
|
||||||
})
|
item.data.pose2d.y
|
||||||
.catch((error) => {
|
]).top
|
||||||
console.error(error.message);
|
})
|
||||||
});
|
console.log('当前数据', testCarList.value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error.message)
|
||||||
|
})
|
||||||
|
|
||||||
let width = getElementWidthByClass('indexpage-container')
|
let width = getElementWidthByClass('indexpage-container')
|
||||||
getImageWidth(imgUrl.value,'width').then((res) => {
|
getImageWidth(imgUrl.value, 'width').then((res) => {
|
||||||
// console.log(res)
|
// console.log(res)
|
||||||
let ratioVal = width / res
|
let ratioVal = width / res
|
||||||
radio.value = ratioVal
|
radio.value = ratioVal
|
||||||
@ -374,15 +548,14 @@ const computedRatio = () => {
|
|||||||
item.radio = radio.value
|
item.radio = radio.value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if(testCarList.value.length){
|
if (testCarList.value.length) {
|
||||||
testCarList.value.forEach((item) => {
|
testCarList.value.forEach((item) => {
|
||||||
item.radio = radio.value
|
item.radio = radio.value
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
getImageWidth(imgUrl.value,'height').then((res) => {
|
getImageWidth(imgUrl.value, 'height').then((res) => {
|
||||||
console.log("高",res)
|
console.log('高', res)
|
||||||
heightVal.value = res
|
heightVal.value = res
|
||||||
})
|
})
|
||||||
// console.log(width)
|
// console.log(width)
|
||||||
@ -390,45 +563,45 @@ const computedRatio = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getImageSize = (url) =>{
|
const getImageSize = (url) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const img = new Image();
|
const img = new Image()
|
||||||
img.src = url;
|
img.src = url
|
||||||
// 图片加载成功时触发
|
// 图片加载成功时触发
|
||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
const width = img.width;
|
const width = img.width
|
||||||
const height = img.height;
|
const height = img.height
|
||||||
resolve({ width, height });
|
resolve({ width, height })
|
||||||
};
|
}
|
||||||
// 图片加载失败时触发
|
// 图片加载失败时触发
|
||||||
img.onerror = () => {
|
img.onerror = () => {
|
||||||
reject(new Error(`Failed to load image from URL 获取图片尺寸失败: ${url}`));
|
reject(new Error(`Failed to load image from URL 获取图片尺寸失败: ${url}`))
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
const convertToFrontendCoordinates = (origin, width, height, target) => {
|
const convertToFrontendCoordinates = (origin, width, height, target) => {
|
||||||
// 提取原点的 x 和 y 坐标
|
// 提取原点的 x 和 y 坐标
|
||||||
const [originX, originY] = origin;
|
const [originX, originY] = origin
|
||||||
// 提取目标点的 x 和 y 坐标
|
// 提取目标点的 x 和 y 坐标
|
||||||
const [targetX, targetY] = target;
|
const [targetX, targetY] = target
|
||||||
|
|
||||||
// 计算目标点相对于原点在 x 方向上的偏移量
|
// 计算目标点相对于原点在 x 方向上的偏移量
|
||||||
const offsetX = targetX - originX;
|
const offsetX = targetX - originX
|
||||||
// 计算目标点相对于原点在 y 方向上的偏移量
|
// 计算目标点相对于原点在 y 方向上的偏移量
|
||||||
const offsetY = targetY - originY;
|
const offsetY = targetY - originY
|
||||||
|
|
||||||
// 计算前端页面中的 left 坐标
|
// 计算前端页面中的 left 坐标
|
||||||
const left = offsetX;
|
const left = offsetX
|
||||||
// 计算前端页面中的 top 坐标,需要考虑坐标系的转换
|
// 计算前端页面中的 top 坐标,需要考虑坐标系的转换
|
||||||
const top = height - offsetY;
|
const top = height - offsetY
|
||||||
|
|
||||||
return {
|
return {
|
||||||
top,
|
top,
|
||||||
left,
|
left,
|
||||||
origin
|
origin
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
const getImageWidth = (imageUrl,name) => {
|
const getImageWidth = (imageUrl, name) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
@ -451,19 +624,62 @@ const getElementWidthByClass = (className) => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
//小车双击
|
//小车双击
|
||||||
const carDbClick = (item,index) => {
|
const carDbClick = (item, index) => {
|
||||||
console.log(item)
|
console.log(item)
|
||||||
carDialogRef.value.open(JSON.parse(JSON.stringify(item)))
|
carDialogRef.value.open(JSON.parse(JSON.stringify(item)))
|
||||||
}
|
}
|
||||||
|
const boxLeft = ref(0)
|
||||||
|
//获取元素距离左边的距离
|
||||||
|
const getLeftPx = () => {
|
||||||
|
let indexpageContainer = document.getElementById('indexpage-container')
|
||||||
|
console.log('距离左边的距离', indexpageContainer.getBoundingClientRect().left)
|
||||||
|
boxLeft.value = indexpageContainer.getBoundingClientRect().left + 6
|
||||||
|
}
|
||||||
|
// 封装监听元素宽度变化的方法
|
||||||
|
const observeWidthChange = (id, callback) => {
|
||||||
|
const targetElement = document.getElementById(id)
|
||||||
|
if (!targetElement) {
|
||||||
|
console.error(`未找到 ID 为 ${id} 的元素`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver((entries) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
const newWidth = entry.contentRect.width
|
||||||
|
callback(newWidth)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
resizeObserver.observe(targetElement)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let stopObserving
|
||||||
defineExpose({ getMapData }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ getMapData }) // 提供 open 方法,用于打开弹窗
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
carPointListFun()
|
carPointListFun()
|
||||||
// getList()
|
// getList()
|
||||||
window.addEventListener('resize', computedRatio)
|
window.addEventListener('resize', computedRatio)
|
||||||
|
stopObserving = observeWidthChange('indexpage-container', (newWidth) => {
|
||||||
|
// 在这里执行宽度变化时的自定义操作
|
||||||
|
// console.log(`元素宽度已变为: ${newWidth}px`);
|
||||||
|
// 你可以添加更多的操作,比如更新组件的状态等
|
||||||
|
getLeftPx()
|
||||||
|
computedRatio()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', computedRatio)
|
window.removeEventListener('resize', computedRatio)
|
||||||
})
|
})
|
||||||
|
// 组件卸载时停止监听
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (stopObserving) {
|
||||||
|
stopObserving()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -471,7 +687,7 @@ onBeforeUnmount(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: rgba(0,0,0,0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
}
|
}
|
||||||
.indexpage-container {
|
.indexpage-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -547,4 +763,84 @@ onBeforeUnmount(() => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.affix-container-left {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 26px;
|
||||||
|
z-index: 999;
|
||||||
|
// overflow: hidden;
|
||||||
|
}
|
||||||
|
.affix-container-left-box {
|
||||||
|
width: 144px;
|
||||||
|
// height: 120px;
|
||||||
|
// background: #ffffff;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-box {
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #eeeeee;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 18px;
|
||||||
|
height: 42px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-left {
|
||||||
|
font-family:
|
||||||
|
PingFangSC,
|
||||||
|
PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(0, 0, 0, 0.88);
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-img {
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-bottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-bottom-img {
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 12px;
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
.affix-container-left-box-item-bottom-left {
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-family:
|
||||||
|
PingFangSC,
|
||||||
|
PingFang SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #98a4bf;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
.affix-container-right{
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999;
|
||||||
|
right: 40px;
|
||||||
|
bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.affix-container-right-item{
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -42,6 +42,7 @@ const downAgv = async () => {
|
|||||||
const data = await MapApi.agvDownload()
|
const data = await MapApi.agvDownload()
|
||||||
download.zip(data, `agv-${new Date().getTime()}.zip`)
|
download.zip(data, `agv-${new Date().getTime()}.zip`)
|
||||||
}
|
}
|
||||||
|
// 筛选出对应的区域对象
|
||||||
const findChildrenByValues = (tree, values) => {
|
const findChildrenByValues = (tree, values) => {
|
||||||
if (!tree || tree.length === 0) {
|
if (!tree || tree.length === 0) {
|
||||||
return null
|
return null
|
||||||
|