Compare commits
No commits in common. "74701d7fb79bbd26b652ab2cb8500caf119239e3" and "3bd363e8aca826ed42e59937e22ff193acfe9269" have entirely different histories.
74701d7fb7
...
3bd363e8ac
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="edit-map-page" @wheel="handleWheel">
|
<div class="edit-map-page">
|
||||||
<div class="top-tool">
|
<div class="top-tool">
|
||||||
<div class="top-tool-list">
|
<div class="top-tool-list">
|
||||||
<div v-for="item in state.topToolList" :key="item.switchType" class="top-tool-item">
|
<div v-for="item in state.topToolList" :key="item.switchType" class="top-tool-item">
|
||||||
@ -155,62 +155,6 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
<!-- 标记 -->
|
|
||||||
<el-popover
|
|
||||||
placement="bottom"
|
|
||||||
trigger="click"
|
|
||||||
v-else-if="item.switchType === 'marker'"
|
|
||||||
width="220"
|
|
||||||
>
|
|
||||||
<template #reference>
|
|
||||||
<div
|
|
||||||
class="tool-item"
|
|
||||||
:class="
|
|
||||||
toolbarSwitchType === item.switchType
|
|
||||||
? 'tool-active'
|
|
||||||
: item.isActive
|
|
||||||
? 'right-tool-active'
|
|
||||||
: ''
|
|
||||||
"
|
|
||||||
@click="toolbarClick(item)"
|
|
||||||
>
|
|
||||||
<Icon :icon="item.icon" :size="24" />
|
|
||||||
<div class="name"> {{ item.name }} </div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<!-- 位置 -->
|
|
||||||
<el-form :model="state.markForm" class="mt-2" label-width="68">
|
|
||||||
<el-form-item label="标记车辆">
|
|
||||||
<el-select
|
|
||||||
v-model="state.markForm.macAddress"
|
|
||||||
placeholder="请选择"
|
|
||||||
@change="macAddressChange"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in state.mapMarkCarList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.robotNo"
|
|
||||||
:value="item.macAddress"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="标记属性" v-if="state.markForm.markProperty">
|
|
||||||
<el-input v-model="state.markForm.markProperty" style="width: 240px" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="原节点" v-if="state.markForm.originalNode">
|
|
||||||
<el-input v-model="state.markForm.originalNode" style="width: 240px" disabled />
|
|
||||||
</el-form-item>
|
|
||||||
<div style="text-align: right">
|
|
||||||
<el-button
|
|
||||||
size="small"
|
|
||||||
style="width: 64px; height: 30px; background: #00329f"
|
|
||||||
color="#00329F"
|
|
||||||
@click="markFormSubmit()"
|
|
||||||
>确认</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</el-popover>
|
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="tool-item"
|
class="tool-item"
|
||||||
@ -236,8 +180,7 @@
|
|||||||
(item.switchType === 'next' &&
|
(item.switchType === 'next' &&
|
||||||
(toolbarSwitchType === 'createLineLibrary' ||
|
(toolbarSwitchType === 'createLineLibrary' ||
|
||||||
toolbarSwitchType === 'createRegion' ||
|
toolbarSwitchType === 'createRegion' ||
|
||||||
toolbarSwitchType === 'drawRoute' ||
|
toolbarSwitchType === 'drawRoute'))
|
||||||
toolbarSwitchType === 'generateLine'))
|
|
||||||
"
|
"
|
||||||
></div>
|
></div>
|
||||||
<el-button
|
<el-button
|
||||||
@ -245,8 +188,7 @@
|
|||||||
item.switchType === 'next' &&
|
item.switchType === 'next' &&
|
||||||
(toolbarSwitchType === 'createLineLibrary' ||
|
(toolbarSwitchType === 'createLineLibrary' ||
|
||||||
toolbarSwitchType === 'createRegion' ||
|
toolbarSwitchType === 'createRegion' ||
|
||||||
toolbarSwitchType === 'drawRoute' ||
|
toolbarSwitchType === 'drawRoute')
|
||||||
toolbarSwitchType === 'generateLine')
|
|
||||||
"
|
"
|
||||||
type="danger"
|
type="danger"
|
||||||
class="selection-area-btn"
|
class="selection-area-btn"
|
||||||
@ -327,10 +269,7 @@
|
|||||||
style="border: none; z-index: 999"
|
style="border: none; z-index: 999"
|
||||||
>
|
>
|
||||||
<!-- 节点合集 -->
|
<!-- 节点合集 -->
|
||||||
<div
|
<div @mousedown="startFromPoint(index, $event)">
|
||||||
@mousedown="startFromPoint(index, $event)"
|
|
||||||
:style="{ width: item.locationWidePx + 'px', height: item.locationDeepPx + 'px' }"
|
|
||||||
>
|
|
||||||
<!-- 1 路径点 -->
|
<!-- 1 路径点 -->
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
class="box-item"
|
class="box-item"
|
||||||
@ -422,33 +361,17 @@
|
|||||||
:x2="Number(state.currentDrawX)"
|
:x2="Number(state.currentDrawX)"
|
||||||
:y2="Number(state.currentDrawY)"
|
:y2="Number(state.currentDrawY)"
|
||||||
stroke="#00329F"
|
stroke="#00329F"
|
||||||
stroke-width="3"
|
stroke-width="4"
|
||||||
/>
|
/>
|
||||||
<template v-if="state.mapRouteList.length > 0">
|
<template v-if="state.mapRouteList.length > 0">
|
||||||
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
||||||
<!-- 定义箭头 -->
|
<!-- 定义箭头 -->
|
||||||
<defs>
|
<defs>
|
||||||
<marker
|
<marker id="forward-arrow" viewBox="0 0 9 9" refX="10" refY="5" orient="auto">
|
||||||
id="forward-arrow"
|
|
||||||
viewBox="0 0 10 10"
|
|
||||||
refX="10"
|
|
||||||
refY="5"
|
|
||||||
orient="auto"
|
|
||||||
markerWidth="2"
|
|
||||||
markerHeight="2"
|
|
||||||
>
|
|
||||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="black" />
|
<path d="M 0 0 L 10 5 L 0 10 z" fill="black" />
|
||||||
</marker>
|
</marker>
|
||||||
<!-- 反向箭头 -->
|
<!-- 反向箭头 -->
|
||||||
<marker
|
<marker id="backward-arrow" viewBox="0 0 9 9" refX="0" refY="5" orient="auto">
|
||||||
id="backward-arrow"
|
|
||||||
viewBox="0 0 10 10"
|
|
||||||
refX="0"
|
|
||||||
refY="5"
|
|
||||||
orient="auto"
|
|
||||||
markerWidth="2"
|
|
||||||
markerHeight="2"
|
|
||||||
>
|
|
||||||
<path d="M 10 0 L 0 5 L 10 10 z" fill="black" />
|
<path d="M 10 0 L 0 5 L 10 10 z" fill="black" />
|
||||||
</marker>
|
</marker>
|
||||||
</defs>
|
</defs>
|
||||||
@ -901,10 +824,10 @@ const mapClick = (e) => {
|
|||||||
locationY: y,
|
locationY: y,
|
||||||
actualLocationX: actualLocationX,
|
actualLocationX: actualLocationX,
|
||||||
actualLocationY: actualLocationY,
|
actualLocationY: actualLocationY,
|
||||||
locationDeep: 40,
|
locationDeep: 50,
|
||||||
locationWide: 40,
|
locationWide: 50,
|
||||||
locationDeepPx: 8,
|
locationDeepPx: 10,
|
||||||
locationWidePx: 8,
|
locationWidePx: 10,
|
||||||
angle: 0,
|
angle: 0,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
@ -1155,22 +1078,16 @@ const state = reactive({
|
|||||||
icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// switchType: 'drawRoute',
|
|
||||||
// name: '框选绘制',
|
|
||||||
// icon: 'ep:semi-select',
|
|
||||||
// isActive: false
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
switchType: 'editRoute',
|
switchType: 'drawRoute',
|
||||||
name: '编辑路线',
|
name: '框选绘制',
|
||||||
icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
switchType: 'generateLine',
|
switchType: 'editRoute',
|
||||||
name: '生成直线',
|
name: '编辑路线',
|
||||||
icon: 'ep:finished',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -1221,14 +1138,7 @@ const state = reactive({
|
|||||||
allMapPointInfo: [], //当前页面上的所有节点的列表
|
allMapPointInfo: [], //当前页面上的所有节点的列表
|
||||||
mapRouteList: [], //当前页面上所有路线的列表
|
mapRouteList: [], //当前页面上所有路线的列表
|
||||||
currentIndex: 0, //当前处在哪条历史记录
|
currentIndex: 0, //当前处在哪条历史记录
|
||||||
currentItemIndex: -1, //当前处在哪个工具
|
currentItemIndex: -1 //当前处在哪个工具
|
||||||
markForm: {
|
|
||||||
macAddress: '', // mac地址
|
|
||||||
markProperty: '', //标记属性
|
|
||||||
originalNode: '', //原节点
|
|
||||||
robotNo: '' //AGV编号
|
|
||||||
}, //标记的表单
|
|
||||||
mapMarkCarList: [] //标记的车辆列表
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const toolbarClick = async (item) => {
|
const toolbarClick = async (item) => {
|
||||||
@ -1419,7 +1329,6 @@ const toolbarClick = async (item) => {
|
|||||||
break
|
break
|
||||||
case 'marker':
|
case 'marker':
|
||||||
// 标记
|
// 标记
|
||||||
mapMark()
|
|
||||||
break
|
break
|
||||||
case 'grid':
|
case 'grid':
|
||||||
//网格
|
//网格
|
||||||
@ -1548,108 +1457,6 @@ const rotationFormSubmit = () => {
|
|||||||
addEditHistory()
|
addEditHistory()
|
||||||
}
|
}
|
||||||
|
|
||||||
//标记
|
|
||||||
const mapMark = async () => {
|
|
||||||
state.mapMarkCarList = await MapApi.getListByMapId(imgBgObj.positionMapId)
|
|
||||||
|
|
||||||
if (state.currentItemIndex != -1) {
|
|
||||||
let item = state.allMapPointInfo[state.currentItemIndex]
|
|
||||||
state.markForm.originalNode = `[${item.locationX},${item.locationY}]`
|
|
||||||
if (item.type == 1) {
|
|
||||||
state.markForm.markProperty = '路径点'
|
|
||||||
} else if (item.type == 2) {
|
|
||||||
state.markForm.markProperty = '库位点'
|
|
||||||
} else if (item.type == 3) {
|
|
||||||
state.markForm.markProperty = '设备点'
|
|
||||||
} else if (item.type == 4) {
|
|
||||||
state.markForm.markProperty = '停车点'
|
|
||||||
} else if (item.type == 5) {
|
|
||||||
state.markForm.markProperty = '区域变更点'
|
|
||||||
} else if (item.type == 6) {
|
|
||||||
state.markForm.markProperty = '等待点'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.markForm.markProperty = ''
|
|
||||||
state.markForm.originalNode = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//标记提交
|
|
||||||
const macAddressChange = (e) => {
|
|
||||||
const targetItem = state.mapMarkCarList.find((item) => item.macAddress === e)
|
|
||||||
if (targetItem) {
|
|
||||||
state.markForm.robotNo = targetItem.robotNo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const markFormSubmit = async () => {
|
|
||||||
if (!state.markForm.macAddress) {
|
|
||||||
message.warning('请选择车辆')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let res = await MapApi.getAGVPointInformation(state.markForm.macAddress)
|
|
||||||
if (res) {
|
|
||||||
let content = JSON.parse(res.content)
|
|
||||||
let point = JSON.parse(content[state.markForm.robotNo]) //标记传过来的数据
|
|
||||||
let pointPx = convertActualToBrowser(point.x, point.y)
|
|
||||||
let actualPoint = disposeEventPoint(pointPx.x, pointPx.y)
|
|
||||||
|
|
||||||
if (state.currentItemIndex !== -1) {
|
|
||||||
state.allMapPointInfo[state.currentItemIndex].locationX = pointPx.x
|
|
||||||
state.allMapPointInfo[state.currentItemIndex].locationY = pointPx.y
|
|
||||||
state.allMapPointInfo[state.currentItemIndex].actualLocationX = actualPoint.actualLocationX
|
|
||||||
state.allMapPointInfo[state.currentItemIndex].actualLocationY = actualPoint.actualLocationY
|
|
||||||
|
|
||||||
//更改路线里的
|
|
||||||
let item = state.allMapPointInfo[state.currentItemIndex]
|
|
||||||
state.mapRouteList.forEach((route) => {
|
|
||||||
if (item.id === route.startingPointId) {
|
|
||||||
route.startPointX = pointPx.x
|
|
||||||
route.startPointY = pointPx.y
|
|
||||||
route.beginHigh = Number(item.locationDeepPx)
|
|
||||||
route.beginWidth = Number(item.locationWidePx)
|
|
||||||
route.actualStartPointX = actualPoint.actualLocationX
|
|
||||||
route.actualStartPointY = actualPoint.actualLocationY
|
|
||||||
}
|
|
||||||
if (item.id === route.endPointId) {
|
|
||||||
route.endPointX = pointPx.x
|
|
||||||
route.endPointY = pointPx.y
|
|
||||||
route.endHigh = Number(item.locationDeepPx)
|
|
||||||
route.endWidth = Number(item.locationWidePx)
|
|
||||||
route.actualEndPointX = actualPoint.actualLocationX
|
|
||||||
route.actualEndPointY = actualPoint.actualLocationY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
addEditHistory()
|
|
||||||
} else {
|
|
||||||
message.warning('未采集到该AGV点位信息')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//新增一个节点
|
|
||||||
state.allMapPointInfo.push({
|
|
||||||
positionMapId: imgBgObj.positionMapId, //地图的id
|
|
||||||
layerSelectionShow: true,
|
|
||||||
locationX: pointPx.x,
|
|
||||||
locationY: pointPx.y,
|
|
||||||
actualLocationX: actualPoint.actualLocationX,
|
|
||||||
actualLocationY: actualPoint.actualLocationY,
|
|
||||||
locationDeep: 40,
|
|
||||||
locationWide: 40,
|
|
||||||
locationDeepPx: 8,
|
|
||||||
locationWidePx: 8,
|
|
||||||
angle: 0,
|
|
||||||
draggable: true,
|
|
||||||
resizable: true,
|
|
||||||
rotatable: false,
|
|
||||||
lockAspectRatio: false, //横纵比
|
|
||||||
mapImageUrl: '',
|
|
||||||
type: 1, //默认类型1 路径节点
|
|
||||||
dataList: [], //存库位的
|
|
||||||
dataObj: {} //存 设备点 停车点 文字
|
|
||||||
})
|
|
||||||
addEditHistory()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//鼠标拖动绘制节点
|
//鼠标拖动绘制节点
|
||||||
// 从点开始绘制
|
// 从点开始绘制
|
||||||
const startFromPoint = (index, event) => {
|
const startFromPoint = (index, event) => {
|
||||||
@ -1675,33 +1482,32 @@ const startFromPoint = (index, event) => {
|
|||||||
//开始框选绘制
|
//开始框选绘制
|
||||||
const startDrawSelection = (event) => {
|
const startDrawSelection = (event) => {
|
||||||
if (
|
if (
|
||||||
toolbarSwitchType.value !== 'createLineLibrary' &&
|
toolbarSwitchType.value === 'createLineLibrary' ||
|
||||||
toolbarSwitchType.value !== 'createRegion' &&
|
toolbarSwitchType.value === 'createRegion' ||
|
||||||
toolbarSwitchType.value !== 'drawRoute' &&
|
toolbarSwitchType.value === 'drawRoute'
|
||||||
toolbarSwitchType.value !== 'generateLine'
|
) {
|
||||||
)
|
const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()
|
||||||
|
|
||||||
|
const x = disposeEventPoints(event).x
|
||||||
|
const y = disposeEventPoints(event).y
|
||||||
|
|
||||||
|
// 确保点击在背景区域内
|
||||||
|
if (x >= 0 && x <= backgroundRect.width && y >= 0 && y <= backgroundRect.height) {
|
||||||
|
state.drawSelectionAreaShow = true
|
||||||
|
state.drawSelectionStartPoint = { x: x, y: y }
|
||||||
|
state.drawSelectionAreaBox = { x: x, y: y, width: 0, height: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
||||||
return
|
return
|
||||||
|
|
||||||
const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()
|
|
||||||
|
|
||||||
const x = disposeEventPoints(event).x
|
|
||||||
const y = disposeEventPoints(event).y
|
|
||||||
|
|
||||||
// 确保点击在背景区域内
|
|
||||||
if (x >= 0 && x <= backgroundRect.width && y >= 0 && y <= backgroundRect.height) {
|
|
||||||
state.drawSelectionAreaShow = true
|
|
||||||
state.drawSelectionStartPoint = { x: x, y: y }
|
|
||||||
state.drawSelectionAreaBox = { x: x, y: y, width: 0, height: 0 }
|
|
||||||
}
|
}
|
||||||
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
|
||||||
}
|
}
|
||||||
// 更新框选区域
|
// 更新框选区域
|
||||||
const updateDrawSelection = (event) => {
|
const updateDrawSelection = (event) => {
|
||||||
if (
|
if (
|
||||||
toolbarSwitchType.value === 'createLineLibrary' ||
|
toolbarSwitchType.value === 'createLineLibrary' ||
|
||||||
toolbarSwitchType.value === 'createRegion' ||
|
toolbarSwitchType.value === 'createRegion' ||
|
||||||
toolbarSwitchType.value === 'drawRoute' ||
|
toolbarSwitchType.value === 'drawRoute'
|
||||||
toolbarSwitchType.value === 'generateLine'
|
|
||||||
) {
|
) {
|
||||||
if (state.drawSelectionAreaShow) {
|
if (state.drawSelectionAreaShow) {
|
||||||
const x = disposeEventPoints(event).x
|
const x = disposeEventPoints(event).x
|
||||||
@ -1726,17 +1532,16 @@ const updateDrawSelection = (event) => {
|
|||||||
state.currentDrawX = x
|
state.currentDrawX = x
|
||||||
state.currentDrawY = y
|
state.currentDrawY = y
|
||||||
}
|
}
|
||||||
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
//结束框选绘制
|
//结束框选绘制
|
||||||
const endDrawSelection = (event) => {
|
const endDrawSelection = (event) => {
|
||||||
if (
|
if (
|
||||||
toolbarSwitchType.value === 'createLineLibrary' ||
|
toolbarSwitchType.value === 'createLineLibrary' ||
|
||||||
toolbarSwitchType.value === 'createRegion' ||
|
toolbarSwitchType.value === 'createRegion' ||
|
||||||
toolbarSwitchType.value === 'drawRoute' ||
|
toolbarSwitchType.value === 'drawRoute'
|
||||||
toolbarSwitchType.value === 'generateLine'
|
|
||||||
) {
|
) {
|
||||||
state.drawSelectionAreaShow = false
|
state.drawSelectionAreaShow = false
|
||||||
state.allDrawSelectionAreaBox.push({ ...state.drawSelectionAreaBox })
|
state.allDrawSelectionAreaBox.push({ ...state.drawSelectionAreaBox })
|
||||||
@ -1831,6 +1636,7 @@ const endDrawSelection = (event) => {
|
|||||||
state.currentDrawX = 0
|
state.currentDrawX = 0
|
||||||
state.currentDrawY = 0
|
state.currentDrawY = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
event.preventDefault() // 阻止默认行为(避免选中图片或文本)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1880,7 +1686,6 @@ const clickDrawSelectionArea = () => {
|
|||||||
item.id
|
item.id
|
||||||
})
|
})
|
||||||
|
|
||||||
//线库
|
|
||||||
if (toolbarSwitchType.value === 'createLineLibrary') {
|
if (toolbarSwitchType.value === 'createLineLibrary') {
|
||||||
//线库
|
//线库
|
||||||
if (binLocation.length < 2) {
|
if (binLocation.length < 2) {
|
||||||
@ -1917,7 +1722,7 @@ const clickDrawSelectionArea = () => {
|
|||||||
removeEventListener() //移除监听
|
removeEventListener() //移除监听
|
||||||
itemAreaSettingDialogRef.value.open(binLocation)
|
itemAreaSettingDialogRef.value.open(binLocation)
|
||||||
}
|
}
|
||||||
//绘制直线
|
|
||||||
if (toolbarSwitchType.value === 'drawRoute') {
|
if (toolbarSwitchType.value === 'drawRoute') {
|
||||||
if (routeList.length !== 2) {
|
if (routeList.length !== 2) {
|
||||||
message.warning('只能选择两个路径点')
|
message.warning('只能选择两个路径点')
|
||||||
@ -1968,105 +1773,6 @@ const clickDrawSelectionArea = () => {
|
|||||||
state.mapRouteList.push(curve)
|
state.mapRouteList.push(curve)
|
||||||
addEditHistory()
|
addEditHistory()
|
||||||
}
|
}
|
||||||
//生成直线
|
|
||||||
if (toolbarSwitchType.value === 'generateLine') {
|
|
||||||
if (routeList.length < 3) {
|
|
||||||
message.warning('至少框选三个点')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let isHaveId = routeList.every((item) => {
|
|
||||||
return item.id
|
|
||||||
})
|
|
||||||
if (!isHaveId) {
|
|
||||||
message.warning('您选择的路径点存在未保存的')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const list = mapPointsToLine(routeList)
|
|
||||||
const idNameMap = {}
|
|
||||||
list.forEach((item) => {
|
|
||||||
idNameMap[item.id] = item
|
|
||||||
})
|
|
||||||
// 遍历第二个数组,更新 name
|
|
||||||
state.allMapPointInfo.forEach((item) => {
|
|
||||||
if (idNameMap[item.id]) {
|
|
||||||
let actualPoint = disposeEventPoint(
|
|
||||||
idNameMap[item.id].locationX,
|
|
||||||
idNameMap[item.id].locationY
|
|
||||||
)
|
|
||||||
item.locationX = idNameMap[item.id].locationX
|
|
||||||
item.locationY = idNameMap[item.id].locationY
|
|
||||||
item.actualLocationX = actualPoint.actualLocationX
|
|
||||||
item.actualLocationY = actualPoint.actualLocationY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
console.log(state.allMapPointInfo)
|
|
||||||
state.mapRouteList.forEach((item) => {
|
|
||||||
if (idNameMap[item.startingPointId]) {
|
|
||||||
let actualPoint = disposeEventPoint(
|
|
||||||
idNameMap[item.startingPointId].locationX,
|
|
||||||
idNameMap[item.startingPointId].locationY
|
|
||||||
)
|
|
||||||
item.startPointX = idNameMap[item.startingPointId].locationX
|
|
||||||
item.startPointY = idNameMap[item.startingPointId].locationY
|
|
||||||
item.actualStartPointX = actualPoint.actualLocationX
|
|
||||||
item.actualStartPointY = actualPoint.actualLocationY
|
|
||||||
}
|
|
||||||
if (idNameMap[item.endPointId]) {
|
|
||||||
let actualPoint = disposeEventPoint(
|
|
||||||
idNameMap[item.endPointId].locationX,
|
|
||||||
idNameMap[item.endPointId].locationY
|
|
||||||
)
|
|
||||||
item.endPointX = idNameMap[item.endPointId].locationX
|
|
||||||
item.endPointY = idNameMap[item.endPointId].locationY
|
|
||||||
item.actualEndPointX = actualPoint.actualLocationX
|
|
||||||
item.actualEndPointY = actualPoint.actualLocationY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
addEditHistory()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//将一个数组中的点位 按照第一个和最后一个排成一条直线
|
|
||||||
const mapPointsToLine = (points) => {
|
|
||||||
if (points.length < 2) {
|
|
||||||
return points
|
|
||||||
}
|
|
||||||
// 取数组的第一项和最后一项
|
|
||||||
const firstPoint = points[0]
|
|
||||||
const lastPoint = points[points.length - 1]
|
|
||||||
|
|
||||||
// 计算直线的斜率
|
|
||||||
const dx = lastPoint.locationX - firstPoint.locationX
|
|
||||||
const dy = lastPoint.locationY - firstPoint.locationY
|
|
||||||
|
|
||||||
if (dx === 0) {
|
|
||||||
// 垂直直线的情况
|
|
||||||
return points.map((point, index) => {
|
|
||||||
if (index === 0 || index === points.length - 1) {
|
|
||||||
return point
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...point,
|
|
||||||
locationX: firstPoint.locationX,
|
|
||||||
locationY: point.locationY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const slope = dy / dx
|
|
||||||
// 计算直线的截距
|
|
||||||
const intercept = firstPoint.locationY - slope * firstPoint.locationX
|
|
||||||
|
|
||||||
// 映射其他点到直线上
|
|
||||||
return points.map((point, index) => {
|
|
||||||
if (index === 0 || index === points.length - 1) {
|
|
||||||
return point
|
|
||||||
}
|
|
||||||
const newY = slope * point.locationX + intercept
|
|
||||||
// 考虑精度问题,这里保留三位小数
|
|
||||||
return {
|
|
||||||
...point,
|
|
||||||
locationY: newY
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
//计算是不是在同一条直线的
|
//计算是不是在同一条直线的
|
||||||
const isStraightLine = (binLocation) => {
|
const isStraightLine = (binLocation) => {
|
||||||
@ -2296,6 +2002,7 @@ const getMapList = async () => {
|
|||||||
imgBgObj.positionMapId = res.id
|
imgBgObj.positionMapId = res.id
|
||||||
imgBgObj.floor = res.floor
|
imgBgObj.floor = res.floor
|
||||||
imgBgObj.area = res.area
|
imgBgObj.area = res.area
|
||||||
|
|
||||||
imgBgObj.width = yamlJson.width
|
imgBgObj.width = yamlJson.width
|
||||||
imgBgObj.height = yamlJson.height
|
imgBgObj.height = yamlJson.height
|
||||||
imgBgObj.origin = yamlJson.origin
|
imgBgObj.origin = yamlJson.origin
|
||||||
@ -2330,8 +2037,8 @@ const getAllNodeList = async () => {
|
|||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
item.dataObj = {}
|
item.dataObj = {}
|
||||||
item.dataList = []
|
item.dataList = []
|
||||||
item.locationDeep = 40
|
item.locationDeep = 50
|
||||||
item.locationWide = 40
|
item.locationWide = 50
|
||||||
item.draggable = true
|
item.draggable = true
|
||||||
item.resizable = false
|
item.resizable = false
|
||||||
item.rotatable = false
|
item.rotatable = false
|
||||||
@ -2594,33 +2301,6 @@ const handleKeyDown = (event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//鼠标滚轮
|
|
||||||
const handleWheel = (event) => {
|
|
||||||
// 判断 Ctrl 键是否被按下
|
|
||||||
if (event.ctrlKey) {
|
|
||||||
// 阻止默认的滚动行为
|
|
||||||
event.preventDefault()
|
|
||||||
|
|
||||||
// 根据滚轮滚动方向调整缩放比例
|
|
||||||
if (event.deltaY < 0) {
|
|
||||||
// 向上滚动,放大
|
|
||||||
//放大
|
|
||||||
if (state.imageChangeMultiple < 4) {
|
|
||||||
state.imageChangeMultiple += 0.2
|
|
||||||
} else {
|
|
||||||
message.warning('不能在放大了')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//缩小
|
|
||||||
if (state.imageChangeMultiple > 0.2) {
|
|
||||||
state.imageChangeMultiple -= 0.2
|
|
||||||
} else {
|
|
||||||
message.warning('不能在缩小了')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const addEventListener = () => {
|
const addEventListener = () => {
|
||||||
window.addEventListener('keydown', handleKeyDown)
|
window.addEventListener('keydown', handleKeyDown)
|
||||||
}
|
}
|
||||||
@ -2770,6 +2450,8 @@ onUnmounted(() => {
|
|||||||
// 20px 20px,
|
// 20px 20px,
|
||||||
// 20px 20px;
|
// 20px 20px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
background-image: repeating-linear-gradient(
|
background-image: repeating-linear-gradient(
|
||||||
to right,
|
to right,
|
||||||
rgba(0, 0, 0, 0.1),
|
rgba(0, 0, 0, 0.1),
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div style="width: 600px; height: 300px; background: #dbeede; position: relative">
|
|
||||||
<div v-for="(item, index) in points" :key="index">
|
|
||||||
<div
|
|
||||||
:style="{
|
|
||||||
position: 'absolute',
|
|
||||||
width: '10px',
|
|
||||||
height: '10px',
|
|
||||||
backgroundColor: '#000',
|
|
||||||
borderRadius: '50%',
|
|
||||||
zIndex: 999,
|
|
||||||
left: item.x + 'px',
|
|
||||||
top: item.y + 'px'
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="width: 600px; height: 300px; background: #b3dcff; position: relative">
|
|
||||||
<div v-for="(item, index) in mappedPoints" :key="index">
|
|
||||||
<div
|
|
||||||
:style="{
|
|
||||||
position: 'absolute',
|
|
||||||
width: '10px',
|
|
||||||
height: '10px',
|
|
||||||
backgroundColor: '#000',
|
|
||||||
borderRadius: '50%',
|
|
||||||
zIndex: 999,
|
|
||||||
left: item.x + 'px',
|
|
||||||
top: item.y + 'px'
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const points = ref([
|
|
||||||
{
|
|
||||||
x: 123.567,
|
|
||||||
y: 178.123
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 255.567,
|
|
||||||
y: 79.123
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 382.567,
|
|
||||||
y: 178.123
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 481.567,
|
|
||||||
y: 238.123
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const mapPointsToLine = (points) => {
|
|
||||||
if (points.length < 2) {
|
|
||||||
return points
|
|
||||||
}
|
|
||||||
// 取数组的第一项和最后一项
|
|
||||||
const firstPoint = points[0]
|
|
||||||
const lastPoint = points[points.length - 1]
|
|
||||||
|
|
||||||
// 计算直线的斜率
|
|
||||||
const dx = lastPoint.x - firstPoint.x
|
|
||||||
const dy = lastPoint.y - firstPoint.y
|
|
||||||
if (dx === 0) {
|
|
||||||
// 垂直直线的情况
|
|
||||||
return points.map((point, index) => {
|
|
||||||
if (index === 0 || index === points.length - 1) {
|
|
||||||
return point
|
|
||||||
}
|
|
||||||
return { x: firstPoint.x, y: point.y }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const slope = dy / dx
|
|
||||||
// 计算直线的截距
|
|
||||||
const intercept = firstPoint.y - slope * firstPoint.x
|
|
||||||
|
|
||||||
// 映射其他点到直线上
|
|
||||||
return points.map((point, index) => {
|
|
||||||
if (index === 0 || index === points.length - 1) {
|
|
||||||
return point
|
|
||||||
}
|
|
||||||
const newY = slope * point.x + intercept
|
|
||||||
return { x: point.x, y: newY }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const mappedPoints = mapPointsToLine(points.value)
|
|
||||||
console.log(mappedPoints)
|
|
||||||
</script>
|
|
@ -23,14 +23,6 @@
|
|||||||
>
|
>
|
||||||
<el-input type="number" v-model="form.locationY" placeholder="请输入" :min="0" />
|
<el-input type="number" v-model="form.locationY" placeholder="请输入" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
|
||||||
label="弧度"
|
|
||||||
prop="locationYaw"
|
|
||||||
required
|
|
||||||
:rules="{ required: true, message: '请输入弧度', trigger: 'change' }"
|
|
||||||
>
|
|
||||||
<el-input type="number" v-model="form.locationYaw" placeholder="请输入" :min="0" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="类型" prop="type" required>
|
<el-form-item label="类型" prop="type" required>
|
||||||
<el-select v-model="form.type" placeholder="请选择类型" @change="typeChange">
|
<el-select v-model="form.type" placeholder="请选择类型" @change="typeChange">
|
||||||
<el-option label="路径点位" :value="1" />
|
<el-option label="路径点位" :value="1" />
|
||||||
@ -41,7 +33,6 @@
|
|||||||
<el-option label="等待点" :value="6" />
|
<el-option label="等待点" :value="6" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<div v-if="form.type === 2 || form.type === 3 || form.type === 4">
|
<div v-if="form.type === 2 || form.type === 3 || form.type === 4">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="层数"
|
label="层数"
|
||||||
@ -181,14 +172,12 @@ const form = ref({
|
|||||||
dataList: [], //存库位的
|
dataList: [], //存库位的
|
||||||
dataObj: {}, //存 设备点 停车点 文字
|
dataObj: {}, //存 设备点 停车点 文字
|
||||||
positionMapId: undefined,
|
positionMapId: undefined,
|
||||||
deviceId: undefined, //设备id
|
deviceId: undefined
|
||||||
locationYaw: undefined //弧度
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = reactive({
|
const rules = reactive({
|
||||||
locationX: [{ required: true, message: '请输入X', trigger: 'blur' }],
|
locationX: [{ required: true, message: '请输入X', trigger: 'blur' }],
|
||||||
locationY: [{ required: true, message: '请输入Y', trigger: 'blur' }],
|
locationY: [{ required: true, message: '请输入Y', trigger: 'blur' }],
|
||||||
locationYaw: [{ required: true, message: '请输入弧度', trigger: 'blur' }],
|
|
||||||
type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
|
type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
|
||||||
layersNumber: [{ required: true, message: '请输入层数', trigger: 'blur' }],
|
layersNumber: [{ required: true, message: '请输入层数', trigger: 'blur' }],
|
||||||
locationNumber: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
locationNumber: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
||||||
@ -267,7 +256,6 @@ const dialogClose = () => {
|
|||||||
|
|
||||||
const equipmentList = ref([]) //用过的设备列表
|
const equipmentList = ref([]) //用过的设备列表
|
||||||
const open = (item, list) => {
|
const open = (item, list) => {
|
||||||
console.log(item)
|
|
||||||
form.value = item
|
form.value = item
|
||||||
form.value.layersNumber = item.dataList?.length || ''
|
form.value.layersNumber = item.dataList?.length || ''
|
||||||
form.value.deviceId = item?.deviceId || item?.dataObj?.id || ''
|
form.value.deviceId = item?.deviceId || item?.dataObj?.id || ''
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
:style="{
|
:style="{
|
||||||
height: heightVal + 'px',
|
height: heightVal + 'px',
|
||||||
cursor: isDrag ? 'pointer' : 'default',
|
cursor: isDrag ? 'pointer' : 'default',
|
||||||
scale: isSizeRadio,
|
scale: isSizeRaio,
|
||||||
transformOrigin: '0 0'
|
transformOrigin: '0 0'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
ref="draggableElement"
|
ref="draggableElement"
|
||||||
>
|
>
|
||||||
<div class="indexpage-container-box">
|
<div class="indexpage-container-box">
|
||||||
<img :src="imgUrl" class="indexpage-container-box-img" />
|
<img :src="imgUrl" alt="" class="indexpage-container-box-img" />
|
||||||
|
|
||||||
<div class="indexpage-container-box-point">
|
<div class="indexpage-container-box-point">
|
||||||
<!-- 连线 -->
|
<!-- 连线 -->
|
||||||
@ -27,27 +27,11 @@
|
|||||||
<template v-for="(item, index) in lineList" :key="index">
|
<template v-for="(item, index) in lineList" :key="index">
|
||||||
<!-- 定义箭头 -->
|
<!-- 定义箭头 -->
|
||||||
<defs>
|
<defs>
|
||||||
<marker
|
<marker id="forward-arrow" viewBox="0 0 10 10" refX="10" refY="5" orient="auto">
|
||||||
id="forward-arrow"
|
|
||||||
viewBox="0 0 10 10"
|
|
||||||
refX="10"
|
|
||||||
refY="5"
|
|
||||||
orient="auto"
|
|
||||||
markerWidth="2"
|
|
||||||
markerHeight="2"
|
|
||||||
>
|
|
||||||
<path d="M 0 0 L 10 5 L 0 10 z" fill="black" />
|
<path d="M 0 0 L 10 5 L 0 10 z" fill="black" />
|
||||||
</marker>
|
</marker>
|
||||||
<!-- 反向箭头 -->
|
<!-- 反向箭头 -->
|
||||||
<marker
|
<marker id="backward-arrow" viewBox="0 0 10 10" refX="0" refY="5" orient="auto">
|
||||||
id="backward-arrow"
|
|
||||||
viewBox="0 0 10 10"
|
|
||||||
refX="0"
|
|
||||||
refY="5"
|
|
||||||
orient="auto"
|
|
||||||
markerWidth="2"
|
|
||||||
markerHeight="2"
|
|
||||||
>
|
|
||||||
<path d="M 10 0 L 0 5 L 10 10 z" fill="black" />
|
<path d="M 10 0 L 0 5 L 10 10 z" fill="black" />
|
||||||
</marker>
|
</marker>
|
||||||
</defs>
|
</defs>
|
||||||
@ -58,7 +42,7 @@
|
|||||||
:x2="Number(item.endPointX) * radio"
|
:x2="Number(item.endPointX) * radio"
|
||||||
:y2="Number(item.endPointY) * radio"
|
:y2="Number(item.endPointY) * radio"
|
||||||
:stroke="item.isSelect ? '#f48924' : '#00329F'"
|
:stroke="item.isSelect ? '#f48924' : '#00329F'"
|
||||||
:stroke-width="4 * radio"
|
:stroke-width="5 * radio"
|
||||||
:marker-start="item.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
:marker-start="item.direction === 2 ? 'url(#double-arrow-start)' : ''"
|
||||||
marker-end="url(#single-arrow)"
|
marker-end="url(#single-arrow)"
|
||||||
@click="handleChooseRoute(item, index)"
|
@click="handleChooseRoute(item, index)"
|
||||||
@ -67,7 +51,7 @@
|
|||||||
:d="getLineMidArrowPath(item)"
|
:d="getLineMidArrowPath(item)"
|
||||||
stroke="none"
|
stroke="none"
|
||||||
fill="black"
|
fill="black"
|
||||||
:stroke-width="4 * radio"
|
stroke-width="4"
|
||||||
:marker-start="item.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="item.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
item.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
item.direction === 2 ? 'url(#forward-arrow)' : 'url(#forward-arrow)'
|
||||||
@ -78,7 +62,7 @@
|
|||||||
<path
|
<path
|
||||||
:d="getCurvePath(item)"
|
:d="getCurvePath(item)"
|
||||||
:stroke="item.isSelect ? '#f48924' : '#00329F'"
|
:stroke="item.isSelect ? '#f48924' : '#00329F'"
|
||||||
:stroke-width="4 * radio"
|
:stroke-width="5 * radio"
|
||||||
fill="none"
|
fill="none"
|
||||||
:marker-start="item.direction === 2 ? 'url(#backward-arrow)' : ''"
|
:marker-start="item.direction === 2 ? 'url(#backward-arrow)' : ''"
|
||||||
:marker-end="
|
:marker-end="
|
||||||
@ -113,6 +97,7 @@
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/chache-4备份 7@2x.png"
|
src="@/assets/imgs/indexPage/chache-4备份 7@2x.png"
|
||||||
|
alt=""
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -122,93 +107,199 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
:style="{
|
:style="{
|
||||||
left:
|
left:
|
||||||
(Number(item.locationX) - Number(item.locationWidePx) / 2) * Number(radio) + 'px',
|
(item.locationX - item.locationWide / 2 / nowObject.showYamlJson.resolution / 100) *
|
||||||
|
radio +
|
||||||
|
'px',
|
||||||
top:
|
top:
|
||||||
(Number(item.locationY) - Number(item.locationDeepPx) / 2) * Number(radio) + 'px',
|
(item.locationY - item.locationDeep / 2 / nowObject.showYamlJson.resolution / 100) *
|
||||||
width: Number(item.locationWidePx) * Number(radio) + 'px',
|
radio +
|
||||||
height: Number(item.locationDeepPx) * Number(radio) + 'px'
|
'px'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<!-- 1 路径点 -->
|
<!-- 库位点 -->
|
||||||
<el-tooltip class="box-item" effect="dark" :content="item.sortNum + ''" placement="top">
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner"
|
||||||
|
v-if="item.showData"
|
||||||
|
:style="{
|
||||||
|
width:
|
||||||
|
(item.showData.locationWide / nowObject.showYamlJson.resolution / 100) * radio +
|
||||||
|
'px',
|
||||||
|
height:
|
||||||
|
(item.showData.locationDeep / nowObject.showYamlJson.resolution / 100) * radio +
|
||||||
|
'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!-- 库位 2-->
|
||||||
|
<div v-if="item.type == 2" style="width: 100%; height: 100%;vertical-align: top;">
|
||||||
|
<el-popover placement="top-start" trigger="hover" width="auto">
|
||||||
|
<template #reference>
|
||||||
|
<img
|
||||||
|
:src="item.imgUrl"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
@dblclick="storeClick(item)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover">
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner-popover-item"
|
||||||
|
style="margin-bottom: 8px"
|
||||||
|
>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-name">
|
||||||
|
库位名:
|
||||||
|
</div>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-value">
|
||||||
|
{{ item.showData.locationNo || '' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner-popover-item"
|
||||||
|
style="margin-bottom: 8px"
|
||||||
|
>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-name">
|
||||||
|
所属线库:
|
||||||
|
</div>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-value">
|
||||||
|
{{ item.showData.laneName || '' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner-popover-item"
|
||||||
|
style="margin-bottom: 8px"
|
||||||
|
>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-name">
|
||||||
|
所属区域:
|
||||||
|
</div>
|
||||||
|
<div class="indexpage-container-box-point-item-inner-popover-value">
|
||||||
|
{{ item.showData.areaName || '' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
<!-- 设备点 -->
|
||||||
|
<div v-if="item.type == 3">
|
||||||
|
<img
|
||||||
|
:src="item.formattedData.mapImageUrl"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 设备点 -->
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner"
|
||||||
|
v-if="item.type == 3"
|
||||||
|
:style="{
|
||||||
|
width:
|
||||||
|
(item.formattedData.locationWide / nowObject.showYamlJson.resolution / 100) *
|
||||||
|
radio +
|
||||||
|
'px',
|
||||||
|
height:
|
||||||
|
(item.formattedData.locationDeep / nowObject.showYamlJson.resolution / 100) *
|
||||||
|
radio +
|
||||||
|
'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
item.formattedData.mapImageUrl
|
||||||
|
? item.formattedData.mapImageUrl
|
||||||
|
: 'https://api.znkjfw.com/admin-api/infra/file/4/get/设备点_png_179_1739327151877.png'
|
||||||
|
"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 停车点 -->
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner"
|
||||||
|
v-if="item.type == 4"
|
||||||
|
:style="{
|
||||||
|
width:
|
||||||
|
(item.formattedData.locationWide / nowObject.showYamlJson.resolution / 100) *
|
||||||
|
radio +
|
||||||
|
'px',
|
||||||
|
height:
|
||||||
|
(item.formattedData.locationDeep / nowObject.showYamlJson.resolution / 100) *
|
||||||
|
radio +
|
||||||
|
'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
item.formattedData.mapImageUrl
|
||||||
|
? item.formattedData.mapImageUrl
|
||||||
|
: 'https://api.znkjfw.com/admin-api/infra/file/4/get/停车场-01_png_179_1739326933020.png'
|
||||||
|
"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 路径点 -->
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner"
|
||||||
|
v-if="item.type == 5"
|
||||||
|
:style="{
|
||||||
|
width: 150 * radio + 'px',
|
||||||
|
height: 150 * radio + 'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
item.formattedData.mapImageUrl
|
||||||
|
? item.formattedData.mapImageUrl
|
||||||
|
: 'https://api.znkjfw.com/admin-api/infra/file/4/get/区域_png_179_1739327151876.png'
|
||||||
|
"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 等待点 -->
|
||||||
|
<div
|
||||||
|
class="indexpage-container-box-point-item-inner"
|
||||||
|
v-if="item.type == 6"
|
||||||
|
:style="{
|
||||||
|
width: 150 * radio + 'px',
|
||||||
|
height: 150 * radio + 'px'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
item.formattedData.mapImageUrl
|
||||||
|
? item.formattedData.mapImageUrl
|
||||||
|
: 'https://api.znkjfw.com/admin-api/infra/file/4/get/等待点_png_179_1739326991439.png'
|
||||||
|
"
|
||||||
|
alt=""
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 普通点 -->
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
:content="item.sortNum + ''"
|
||||||
|
placement="top"
|
||||||
|
v-if="item.type == 1"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-if="item.type === 1"
|
|
||||||
:style="{
|
:style="{
|
||||||
width: Number(item.locationWidePx) * Number(radio) + 'px',
|
width: 10 * radio + 'px',
|
||||||
height: Number(item.locationDeepPx) * Number(radio) + 'px',
|
height: 10 * radio + 'px',
|
||||||
backgroundColor: '#000',
|
background: '#000',
|
||||||
borderRadius: '50%'
|
borderRadius: '50%'
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<!-- 库位点 -->
|
|
||||||
<el-popover placement="top-start" trigger="hover" width="auto">
|
|
||||||
<template #reference>
|
|
||||||
<img
|
|
||||||
v-if="item.showData && item.type == 2"
|
|
||||||
:src="item.imgUrl"
|
|
||||||
:style="nodeStyle(item, index)"
|
|
||||||
@dblclick="storeClick(item)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<div>
|
|
||||||
<div class="indexpage-popover-item">
|
|
||||||
<div> 库位名: </div>
|
|
||||||
<div>
|
|
||||||
{{ item.showData?.locationNo || '' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="indexpage-popover-item">
|
|
||||||
<div> 所属线库: </div>
|
|
||||||
<div>
|
|
||||||
{{ item.showData?.laneName || '' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="indexpage-popover-item">
|
|
||||||
<div> 所属区域: </div>
|
|
||||||
<div>
|
|
||||||
{{ item.showData?.areaName || '' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-popover>
|
|
||||||
<!-- 设备点 -->
|
|
||||||
<img
|
|
||||||
v-if="item.type == 3"
|
|
||||||
:src="
|
|
||||||
item.formattedData.mapImageUrl ||
|
|
||||||
'https://api.znkjfw.com/admin-api/infra/file/4/get/设备点_png_179_1739327151877.png'
|
|
||||||
"
|
|
||||||
:style="nodeStyle(item, index)"
|
|
||||||
/>
|
|
||||||
<!-- 停车点 -->
|
|
||||||
<img
|
|
||||||
v-if="item.type == 4"
|
|
||||||
:src="
|
|
||||||
item.formattedData.mapImageUrl ||
|
|
||||||
'https://api.znkjfw.com/admin-api/infra/file/4/get/停车场-01_png_179_1739326933020.png'
|
|
||||||
"
|
|
||||||
:style="nodeStyle(item, index)"
|
|
||||||
/>
|
|
||||||
<!-- 路径点 -->
|
|
||||||
<img
|
|
||||||
v-if="item.type == 5"
|
|
||||||
:src="
|
|
||||||
item.formattedData.mapImageUrl ||
|
|
||||||
'https://api.znkjfw.com/admin-api/infra/file/4/get/区域_png_179_1739327151876.png'
|
|
||||||
"
|
|
||||||
:style="nodeStyle(item, index)"
|
|
||||||
/>
|
|
||||||
<!-- 等待点 -->
|
|
||||||
<img
|
|
||||||
v-if="item.type == 6"
|
|
||||||
:src="
|
|
||||||
item.formattedData.mapImageUrl ||
|
|
||||||
'https://api.znkjfw.com/admin-api/infra/file/4/get/等待点_png_179_1739326991439.png'
|
|
||||||
"
|
|
||||||
:style="nodeStyle(item, index)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -220,7 +311,7 @@
|
|||||||
<div
|
<div
|
||||||
class="affix-container-left-box-item-box"
|
class="affix-container-left-box-item-box"
|
||||||
:style="{
|
:style="{
|
||||||
height: legendObj.legendShow ? '5.25rem' : '0',
|
height: legendObj.legendShow ? '84px' : '0',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
transition: 'all 0.3s ease-in-out'
|
transition: 'all 0.3s ease-in-out'
|
||||||
}"
|
}"
|
||||||
@ -229,12 +320,14 @@
|
|||||||
<div class="affix-container-left-box-item-left"> 行驶路线 </div>
|
<div class="affix-container-left-box-item-left"> 行驶路线 </div>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
||||||
|
alt=""
|
||||||
class="affix-container-left-box-item-img"
|
class="affix-container-left-box-item-img"
|
||||||
v-if="legendObj.driveLineShow"
|
v-if="legendObj.driveLineShow"
|
||||||
@click="changDriveLineShow"
|
@click="changDriveLineShow"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/yanjing_yincang_o.png"
|
src="@/assets/imgs/indexPage/yanjing_yincang_o.png"
|
||||||
|
alt=""
|
||||||
class="affix-container-left-box-item-img"
|
class="affix-container-left-box-item-img"
|
||||||
v-if="!legendObj.driveLineShow"
|
v-if="!legendObj.driveLineShow"
|
||||||
@click="changDriveLineShow"
|
@click="changDriveLineShow"
|
||||||
@ -244,12 +337,14 @@
|
|||||||
<div class="affix-container-left-box-item-left"> 车辆 </div>
|
<div class="affix-container-left-box-item-left"> 车辆 </div>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
src="@/assets/imgs/indexPage/yanjing_xianshi_o.png"
|
||||||
|
alt=""
|
||||||
class="affix-container-left-box-item-img"
|
class="affix-container-left-box-item-img"
|
||||||
v-if="legendObj.carShow"
|
v-if="legendObj.carShow"
|
||||||
@click="changCarShow"
|
@click="changCarShow"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/yanjing_yincang_o.png"
|
src="@/assets/imgs/indexPage/yanjing_yincang_o.png"
|
||||||
|
alt=""
|
||||||
class="affix-container-left-box-item-img"
|
class="affix-container-left-box-item-img"
|
||||||
v-if="!legendObj.carShow"
|
v-if="!legendObj.carShow"
|
||||||
@click="changCarShow"
|
@click="changCarShow"
|
||||||
@ -263,6 +358,7 @@
|
|||||||
<div class="affix-container-left-box-item-bottom-left"> 图例 </div>
|
<div class="affix-container-left-box-item-bottom-left"> 图例 </div>
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/zhankai@2x.png"
|
src="@/assets/imgs/indexPage/zhankai@2x.png"
|
||||||
|
alt=""
|
||||||
class="affix-container-left-box-item-bottom-img"
|
class="affix-container-left-box-item-bottom-img"
|
||||||
:style="{
|
:style="{
|
||||||
transform: legendObj.legendShow ? 'rotate(180deg)' : 'rotate(0deg)',
|
transform: legendObj.legendShow ? 'rotate(180deg)' : 'rotate(0deg)',
|
||||||
@ -277,12 +373,13 @@
|
|||||||
<div class="affix-container-right" v-if="!isAllBoard">
|
<div class="affix-container-right" v-if="!isAllBoard">
|
||||||
<!-- 拖拽 -->
|
<!-- 拖拽 -->
|
||||||
<div class="affix-container-right-item" @click="changeIsDrag">
|
<div class="affix-container-right-item" @click="changeIsDrag">
|
||||||
<img src="@/assets/imgs/indexPage/编组 12.png" style="width: 100%; height: 100%" />
|
<img src="@/assets/imgs/indexPage/编组 12.png" alt="" style="width: 100%; height: 100%" />
|
||||||
</div>
|
</div>
|
||||||
<!-- 放大 -->
|
<!-- 放大 -->
|
||||||
<div class="affix-container-right-item">
|
<div class="affix-container-right-item">
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/编组 14.png"
|
src="@/assets/imgs/indexPage/编组 14.png"
|
||||||
|
alt=""
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@click="changeSizeRaio(0.2)"
|
@click="changeSizeRaio(0.2)"
|
||||||
/>
|
/>
|
||||||
@ -291,6 +388,7 @@
|
|||||||
<div class="affix-container-right-item">
|
<div class="affix-container-right-item">
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/编组 15.png"
|
src="@/assets/imgs/indexPage/编组 15.png"
|
||||||
|
alt=""
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@click="changeSizeRaio(-0.2)"
|
@click="changeSizeRaio(-0.2)"
|
||||||
/>
|
/>
|
||||||
@ -299,6 +397,7 @@
|
|||||||
<div class="affix-container-right-item">
|
<div class="affix-container-right-item">
|
||||||
<img
|
<img
|
||||||
src="@/assets/imgs/indexPage/编组 22.png"
|
src="@/assets/imgs/indexPage/编组 22.png"
|
||||||
|
alt=""
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@click="toggleFullScreen"
|
@click="toggleFullScreen"
|
||||||
/>
|
/>
|
||||||
@ -338,32 +437,25 @@ const nowObject = ref(null) // 地图当前对象 父组件传过来的
|
|||||||
const testCarList = ref([]) //小车数组
|
const testCarList = ref([]) //小车数组
|
||||||
const carWidth = ref(60)
|
const carWidth = ref(60)
|
||||||
const carHeight = ref(32)
|
const carHeight = ref(32)
|
||||||
|
|
||||||
const nodeStyle = (item, index) => {
|
|
||||||
return {
|
|
||||||
verticalAlign: 'top',
|
|
||||||
objectFit: 'cover',
|
|
||||||
width: Number(item.locationWidePx) * Number(radio.value) + 'px',
|
|
||||||
height: Number(item.locationDeepPx) * Number(radio.value) + 'px'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义属性
|
// 定义属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 当前选中的链接
|
// 当前选中的链接
|
||||||
isAllBoard: propTypes.bool.def(false)
|
isAllBoard: propTypes.bool.def(false)
|
||||||
})
|
})
|
||||||
const convertActualToBrowser = (pointX, pointY) => {
|
const convertActualToBrowser = (pointX, pointY) => {
|
||||||
let resolution = Number(nowObject.value.showYamlJson.resolution)
|
const y1 =
|
||||||
let origin = nowObject.value.showYamlJson.origin
|
Number(nowObject.value.showYamlJson.origin[1]) +
|
||||||
|
Number(nowObject.value.showYamlJson.height) * Number(nowObject.value.showYamlJson.resolution)
|
||||||
const y1 = Number(origin[1]) + Number(nowObject.value.showYamlJson.height) * resolution
|
let x = Math.max(Number(pointX) - Number(nowObject.value.showYamlJson.origin[0]), 0)
|
||||||
let x = Math.max(Number(pointX) - Number(origin[0]), 0)
|
|
||||||
let y = Math.max(y1 - Number(pointY), 0)
|
let y = Math.max(y1 - Number(pointY), 0)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
x: x / resolution - carWidth.value / resolution / 100 / 2,
|
x:
|
||||||
y: y / resolution - carHeight.value / resolution / 100 / 2
|
x / nowObject.value.showYamlJson.resolution -
|
||||||
|
carWidth.value / nowObject.value.showYamlJson.resolution / 100 / 2,
|
||||||
|
y:
|
||||||
|
y / nowObject.value.showYamlJson.resolution -
|
||||||
|
carHeight.value / nowObject.value.showYamlJson.resolution / 100 / 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//是否可以拖拽
|
//是否可以拖拽
|
||||||
@ -413,12 +505,12 @@ const getCurvePath = (curve) => {
|
|||||||
return `M ${startPointX} ${startPointY} C ${curve.beginControlX * radio.value} ${curve.beginControlY * radio.value}, ${curve.endControlX * radio.value} ${curve.endControlY * radio.value}, ${endPointX} ${endPointY}`
|
return `M ${startPointX} ${startPointY} C ${curve.beginControlX * radio.value} ${curve.beginControlY * radio.value}, ${curve.endControlX * radio.value} ${curve.endControlY * radio.value}, ${endPointX} ${endPointY}`
|
||||||
}
|
}
|
||||||
//放大缩小
|
//放大缩小
|
||||||
const isSizeRadio = ref(1)
|
const isSizeRaio = ref(1)
|
||||||
const changeSizeRaio = (type) => {
|
const changeSizeRaio = (type) => {
|
||||||
if (type < 0 && isSizeRadio.value + type <= 0) {
|
if (type < 0 && isSizeRaio.value + type <= 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
isSizeRadio.value += type
|
isSizeRaio.value += type
|
||||||
}
|
}
|
||||||
//图层状态
|
//图层状态
|
||||||
const legendObj = reactive({
|
const legendObj = reactive({
|
||||||
@ -524,22 +616,33 @@ const toggleFullScreen = () => {
|
|||||||
|
|
||||||
//库位双击
|
//库位双击
|
||||||
const storeClick = async (item) => {
|
const storeClick = async (item) => {
|
||||||
|
// console.log(item)
|
||||||
let storeData = await MapApi.houseLocationGetByMapItemId({
|
let storeData = await MapApi.houseLocationGetByMapItemId({
|
||||||
mapId: item.positionMapId,
|
mapId: item.positionMapId,
|
||||||
mapItemId: item.id
|
mapItemId: item.id
|
||||||
})
|
})
|
||||||
|
// console.log(storeData)
|
||||||
storeDialogRef.value.open(JSON.parse(JSON.stringify(storeData)))
|
storeDialogRef.value.open(JSON.parse(JSON.stringify(storeData)))
|
||||||
}
|
}
|
||||||
const lineList = ref([])
|
const lineList = ref([])
|
||||||
const pointList = ref([])
|
const pointList = ref([])
|
||||||
const getPositionMapListFun = async (positionMapId) => {
|
const getPositionMapListFun = async (positionMapId) => {
|
||||||
pointList.value = await MapApi.getPositionMapItemList({ positionMapId: positionMapId })
|
// console.log(positionMapId)
|
||||||
|
let data = await MapApi.getPositionMapItemList({ positionMapId: positionMapId })
|
||||||
pointList.value?.forEach((item) => {
|
// console.log(data)
|
||||||
item.formattedData = item.dataJson ? JSON.parse(item.dataJson) : ''
|
if (data && data.length > 0) {
|
||||||
item.showData = item.dataJson ? JSON.parse(item.dataJson)[0] : null
|
data.forEach((item) => {
|
||||||
item.imgUrl = formatTypeImg(item.type)
|
// console.log(JSON.parse(item.dataJson))
|
||||||
|
item.formattedData = item.dataJson ? JSON.parse(item.dataJson) : ''
|
||||||
|
item.showData = item.dataJson ? JSON.parse(item.dataJson)[0] : null
|
||||||
|
item.imgUrl = formatteTypeImg(item.type)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// console.log(data)
|
||||||
|
pointList.value = data
|
||||||
|
|
||||||
|
// console.log('=======================', pointList.value)
|
||||||
|
pointList.value.forEach((item) => {
|
||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
item.locationDeep = 40
|
item.locationDeep = 40
|
||||||
item.locationWide = 40
|
item.locationWide = 40
|
||||||
@ -559,25 +662,10 @@ const getPositionMapListFun = async (positionMapId) => {
|
|||||||
item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
|
item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
|
||||||
item.locationDeep = item.dataObj.locationDeep
|
item.locationDeep = item.dataObj.locationDeep
|
||||||
item.locationWide = item.dataObj.locationWide
|
item.locationWide = item.dataObj.locationWide
|
||||||
}
|
} else if (item.type === 7) {
|
||||||
//要将实际的cm改成px
|
|
||||||
if (item.locationWide && item.locationDeep) {
|
|
||||||
let pxObj = cmConversionPx(item.locationWide, item.locationDeep)
|
|
||||||
item.locationWidePx = pxObj.pWidth
|
|
||||||
item.locationDeepPx = pxObj.pHeight
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//将节点实际宽高cm转换成px
|
|
||||||
const cmConversionPx = (cWidth, cHeight) => {
|
|
||||||
let pWidth = Number(cWidth) / Number(nowObject.value.showYamlJson.resolution) / 100
|
|
||||||
let pHeight = Number(cHeight) / Number(nowObject.value.showYamlJson.resolution) / 100
|
|
||||||
return {
|
|
||||||
pWidth,
|
|
||||||
pHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const draggableElement = ref(null)
|
const draggableElement = ref(null)
|
||||||
const resetPosition = () => {
|
const resetPosition = () => {
|
||||||
if (draggableElement.value) {
|
if (draggableElement.value) {
|
||||||
@ -630,7 +718,7 @@ const calculateDistanceAndAngle = (point1, point2) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatTypeImg = (type) => {
|
const formatteTypeImg = (type) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
return ''
|
return ''
|
||||||
@ -688,7 +776,7 @@ const linkWebSocket = (url) => {
|
|||||||
[
|
[
|
||||||
h(
|
h(
|
||||||
'span',
|
'span',
|
||||||
{ style: 'color: rgba(255,255,255,0.88);font-size: .875rem;' },
|
{ style: 'color: rgba(255,255,255,0.88);font-size: 14px;' },
|
||||||
`${JSON.parse(jsonMsg.content)}`
|
`${JSON.parse(jsonMsg.content)}`
|
||||||
),
|
),
|
||||||
h(
|
h(
|
||||||
@ -696,7 +784,7 @@ const linkWebSocket = (url) => {
|
|||||||
{
|
{
|
||||||
onClick: () => lookError(),
|
onClick: () => lookError(),
|
||||||
style:
|
style:
|
||||||
'color: rgba(255,255,255,0.88);font-size: .875rem;cursor: pointer;text-decoration-line: underline;margin-left: 2rem;'
|
'color: rgba(255,255,255,0.88);font-size: 14px;cursor: pointer;text-decoration-line: underline;margin-left: 32px;'
|
||||||
},
|
},
|
||||||
'详情'
|
'详情'
|
||||||
)
|
)
|
||||||
@ -735,8 +823,9 @@ const getMapData = async (item) => {
|
|||||||
testCarList.value = []
|
testCarList.value = []
|
||||||
nowObject.value = JSON.parse(JSON.stringify(item))
|
nowObject.value = JSON.parse(JSON.stringify(item))
|
||||||
nowObject.value.showYamlJson = JSON.parse(item.yamlJson)
|
nowObject.value.showYamlJson = JSON.parse(item.yamlJson)
|
||||||
let websocketUrl = `${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}`
|
||||||
linkWebSocket(websocketUrl)
|
// console.log(websoketUrl)
|
||||||
|
linkWebSocket(websoketUrl)
|
||||||
getPositionMapListFun(nowObject.value.id)
|
getPositionMapListFun(nowObject.value.id)
|
||||||
emit('transmitMapInfo', {
|
emit('transmitMapInfo', {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
@ -767,14 +856,17 @@ const computedRatio = () => {
|
|||||||
//这段代码之后会删掉 yaml会给原始宽高
|
//这段代码之后会删掉 yaml会给原始宽高
|
||||||
getImageSize(imgUrl.value)
|
getImageSize(imgUrl.value)
|
||||||
.then(({ width, height }) => {
|
.then(({ width, height }) => {
|
||||||
|
// console.log("原始地图的宽高",JSON.parse(nowObject.value.yamlJson))
|
||||||
if (testCarList.value.length) {
|
if (testCarList.value.length) {
|
||||||
testCarList.value.forEach((item) => {
|
testCarList.value.forEach((item) => {
|
||||||
|
console.log('dayin', 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 = convertActualToBrowser(item.data.pose2d.x, item.data.pose2d.y).x
|
item.realX = convertActualToBrowser(item.data.pose2d.x, item.data.pose2d.y).x
|
||||||
item.realY = convertActualToBrowser(item.data.pose2d.x, item.data.pose2d.y).y
|
item.realY = convertActualToBrowser(item.data.pose2d.x, item.data.pose2d.y).y
|
||||||
})
|
})
|
||||||
|
// console.log('当前数据', testCarList.value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -799,8 +891,10 @@ const computedRatio = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
getImageWidth(imgUrl.value, 'height').then((res) => {
|
getImageWidth(imgUrl.value, 'height').then((res) => {
|
||||||
|
// console.log('高', res)
|
||||||
heightVal.value = res * radio.value
|
heightVal.value = res * radio.value
|
||||||
})
|
})
|
||||||
|
// console.log(width)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -808,6 +902,7 @@ const computedRatio = () => {
|
|||||||
// 获取地图连线列表
|
// 获取地图连线列表
|
||||||
const getMapLineList = () => {
|
const getMapLineList = () => {
|
||||||
MapApi.mapLineListGet({ positionMapId: nowObject.value.id }).then((res) => {
|
MapApi.mapLineListGet({ positionMapId: nowObject.value.id }).then((res) => {
|
||||||
|
// console.log(res)
|
||||||
lineList.value = res
|
lineList.value = res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -952,9 +1047,9 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
.indexpage-container .affix-container-top {
|
.indexpage-container .affix-container-top {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5rem;
|
height: 80px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-bottom: 0.0625rem solid #f5f5f5;
|
border-bottom: 1px solid #f5f5f5;
|
||||||
}
|
}
|
||||||
.indexpage-container-box-point {
|
.indexpage-container-box-point {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -965,12 +1060,11 @@ onUnmounted(() => {
|
|||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
.indexpage-container-box-point-item {
|
.indexpage-container-box-point-item {
|
||||||
box-sizing: border-box;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.scrollbar-flex-content {
|
.scrollbar-flex-content {
|
||||||
padding: 0.125rem 0.375rem;
|
padding: 2px 6px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -980,11 +1074,11 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 5.625rem;
|
width: 90px;
|
||||||
height: 1.875rem;
|
height: 30px;
|
||||||
margin: 0.625rem 0.375rem;
|
margin: 10px 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 0.25rem;
|
border-radius: 4px;
|
||||||
background: var(--el-color-primary-light-9);
|
background: var(--el-color-primary-light-9);
|
||||||
color: var(--el-color-primary);
|
color: var(--el-color-primary);
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -1005,15 +1099,14 @@ onUnmounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.indexpage-popover-item {
|
.indexpage-container-box-point-item-inner-popover-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
font-family:
|
font-family:
|
||||||
PingFangSC,
|
PingFangSC,
|
||||||
PingFang SC;
|
PingFang SC;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 0.875rem;
|
font-size: 14px;
|
||||||
color: #0d162a;
|
color: #0d162a;
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
}
|
||||||
.line-box {
|
.line-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -1024,21 +1117,21 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
.affix-container-left {
|
.affix-container-left {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 1.625rem;
|
bottom: 26px;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
}
|
}
|
||||||
.affix-container-left-box {
|
.affix-container-left-box {
|
||||||
width: 9rem;
|
width: 144px;
|
||||||
}
|
}
|
||||||
.affix-container-left-box-item-box {
|
.affix-container-left-box-item-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 0.0625rem solid #eeeeee;
|
border-bottom: 1px solid #eeeeee;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
.affix-container-left-box-item {
|
.affix-container-left-box-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 1.125rem;
|
padding: 0 18px;
|
||||||
height: 2.625rem;
|
height: 42px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -1048,18 +1141,18 @@ onUnmounted(() => {
|
|||||||
PingFangSC,
|
PingFangSC,
|
||||||
PingFang SC;
|
PingFang SC;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 0.875rem;
|
font-size: 14px;
|
||||||
color: rgba(0, 0, 0, 0.88);
|
color: rgba(0, 0, 0, 0.88);
|
||||||
}
|
}
|
||||||
.affix-container-left-box-item-img {
|
.affix-container-left-box-item-img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 1.25rem;
|
width: 20px;
|
||||||
height: 0.75rem;
|
height: 12px;
|
||||||
}
|
}
|
||||||
.affix-container-left-box-item-bottom {
|
.affix-container-left-box-item-bottom {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 2.25rem;
|
height: 36px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -1069,8 +1162,8 @@ onUnmounted(() => {
|
|||||||
.affix-container-left-box-item-bottom-img {
|
.affix-container-left-box-item-bottom-img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 0.75rem;
|
width: 12px;
|
||||||
height: 0.4375rem;
|
height: 7px;
|
||||||
}
|
}
|
||||||
.affix-container-left-box-item-bottom-left {
|
.affix-container-left-box-item-bottom-left {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -1079,24 +1172,24 @@ onUnmounted(() => {
|
|||||||
PingFangSC,
|
PingFangSC,
|
||||||
PingFang SC;
|
PingFang SC;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 1rem;
|
font-size: 16px;
|
||||||
color: #98a4bf;
|
color: #98a4bf;
|
||||||
margin-right: 0.125rem;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
.affix-container-right {
|
.affix-container-right {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
right: 2.5rem;
|
right: 40px;
|
||||||
bottom: 1.25rem;
|
bottom: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.affix-container-right-item {
|
.affix-container-right-item {
|
||||||
width: 1.75rem;
|
width: 28px;
|
||||||
height: 1.75rem;
|
height: 28px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-left: 0.5rem;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -333,6 +333,7 @@
|
|||||||
>
|
>
|
||||||
<!-- 1 路径点 -->
|
<!-- 1 路径点 -->
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
:content="item.sortNum || '节点未保存'"
|
:content="item.sortNum || '节点未保存'"
|
||||||
placement="top"
|
placement="top"
|
||||||
@ -421,7 +422,7 @@
|
|||||||
:x2="Number(state.currentDrawX)"
|
:x2="Number(state.currentDrawX)"
|
||||||
:y2="Number(state.currentDrawY)"
|
:y2="Number(state.currentDrawY)"
|
||||||
stroke="#00329F"
|
stroke="#00329F"
|
||||||
stroke-width="4"
|
stroke-width="3"
|
||||||
/>
|
/>
|
||||||
<template v-if="state.mapRouteList.length > 0">
|
<template v-if="state.mapRouteList.length > 0">
|
||||||
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
<template v-for="(curve, index) in state.mapRouteList" :key="index">
|
||||||
@ -1154,12 +1155,12 @@ const state = reactive({
|
|||||||
icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// switchType: 'drawRoute',
|
switchType: 'drawRoute',
|
||||||
// name: '框选绘制',
|
name: '框选绘制',
|
||||||
// icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
// isActive: false
|
isActive: false
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
switchType: 'editRoute',
|
switchType: 'editRoute',
|
||||||
name: '编辑路线',
|
name: '编辑路线',
|
||||||
@ -2025,45 +2026,45 @@ const clickDrawSelectionArea = () => {
|
|||||||
}
|
}
|
||||||
//将一个数组中的点位 按照第一个和最后一个排成一条直线
|
//将一个数组中的点位 按照第一个和最后一个排成一条直线
|
||||||
const mapPointsToLine = (points) => {
|
const mapPointsToLine = (points) => {
|
||||||
// 找出 locationX 最大和最小的项
|
if (points.length < 2) {
|
||||||
let minXPoint = points[0]
|
return points
|
||||||
let maxXPoint = points[0]
|
}
|
||||||
points.forEach((point) => {
|
// 取数组的第一项和最后一项
|
||||||
if (point.locationX < minXPoint.locationX) {
|
const firstPoint = points[0]
|
||||||
minXPoint = point
|
const lastPoint = points[points.length - 1]
|
||||||
}
|
|
||||||
if (point.locationX > maxXPoint.locationX) {
|
|
||||||
maxXPoint = point
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const dx = maxXPoint.locationX - minXPoint.locationX
|
// 计算直线的斜率
|
||||||
const dy = maxXPoint.locationY - minXPoint.locationY
|
const dx = lastPoint.locationX - firstPoint.locationX
|
||||||
|
const dy = lastPoint.locationY - firstPoint.locationY
|
||||||
|
|
||||||
// 处理垂直直线的情况
|
|
||||||
if (dx === 0) {
|
if (dx === 0) {
|
||||||
return points.map((point) => {
|
// 垂直直线的情况
|
||||||
if (point === minXPoint || point === maxXPoint) {
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
return point
|
return point
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...point,
|
...point,
|
||||||
locationX: minXPoint.locationX
|
locationX: firstPoint.locationX,
|
||||||
|
locationY: point.locationY
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const slope = dy / dx
|
const slope = dy / dx
|
||||||
const intercept = minXPoint.locationY - slope * minXPoint.locationX
|
// 计算直线的截距
|
||||||
|
const intercept = firstPoint.locationY - slope * firstPoint.locationX
|
||||||
|
|
||||||
return points.map((point) => {
|
// 映射其他点到直线上
|
||||||
if (point === minXPoint || point === maxXPoint) {
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
return point
|
return point
|
||||||
}
|
}
|
||||||
const newY = slope * point.locationX + intercept
|
const newY = slope * point.locationX + intercept
|
||||||
|
// 考虑精度问题,这里保留三位小数
|
||||||
|
const roundedY = parseFloat(newY.toFixed(8))
|
||||||
return {
|
return {
|
||||||
...point,
|
...point,
|
||||||
locationY: newY
|
locationY: roundedY
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,130 +1,94 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div style="width: 600px; height: 300px; background: #dbeede; position: relative">
|
||||||
@mousedown="startSelection"
|
<div v-for="(item, index) in points" :key="index">
|
||||||
@mousemove="updateSelection"
|
<div
|
||||||
@mouseup="endSelection"
|
:style="{
|
||||||
style="position: relative; width: 100vw; height: 100vh"
|
position: 'absolute',
|
||||||
>
|
width: '10px',
|
||||||
<!-- 绘制所有框选区域 -->
|
height: '10px',
|
||||||
<div
|
backgroundColor: '#000',
|
||||||
v-for="(rect, index) in selectionRects"
|
borderRadius: '50%',
|
||||||
:key="index"
|
zIndex: 999,
|
||||||
:style="{
|
left: item.x + 'px',
|
||||||
position: 'absolute',
|
top: item.y + 'px'
|
||||||
left: `${rect.left}px`,
|
}"
|
||||||
top: `${rect.top}px`,
|
></div>
|
||||||
width: `${rect.width}px`,
|
</div>
|
||||||
height: `${rect.height}px`,
|
</div>
|
||||||
backgroundColor: 'rgba(0, 0, 255, 0.2)',
|
<div style="width: 600px; height: 300px; background: #b3dcff; position: relative">
|
||||||
border: '1px solid blue'
|
<div v-for="(item, index) in mappedPoints" :key="index">
|
||||||
}"
|
<div
|
||||||
></div>
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
<!-- 绘制点位 -->
|
width: '10px',
|
||||||
<div
|
height: '10px',
|
||||||
v-for="(point, index) in points"
|
backgroundColor: '#000',
|
||||||
:key="index"
|
borderRadius: '50%',
|
||||||
:style="{
|
zIndex: 999,
|
||||||
position: 'absolute',
|
left: item.x + 'px',
|
||||||
left: `${point.x}px`,
|
top: item.y + 'px'
|
||||||
top: `${point.y}px`,
|
}"
|
||||||
width: '10px',
|
></div>
|
||||||
height: '10px',
|
</div>
|
||||||
backgroundColor: selectedPoints.includes(point) ? 'red' : 'green',
|
|
||||||
borderRadius: '50%'
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<!-- 确认按钮 -->
|
|
||||||
<button @click="confirmSelection" style="position: fixed; bottom: 20px; right: 20px">
|
|
||||||
确认
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
export default {
|
const points = ref([
|
||||||
setup() {
|
{
|
||||||
const points = ref([
|
x: 123.567,
|
||||||
{ x: 10, y: 10 },
|
y: 178.123
|
||||||
{ x: 30, y: 100 },
|
},
|
||||||
{ x: 40, y: 40 },
|
{
|
||||||
{ x: 230, y: 400 },
|
x: 255.567,
|
||||||
{ x: 750, y: 640 }
|
y: 79.123
|
||||||
])
|
},
|
||||||
|
{
|
||||||
const isSelecting = ref(false)
|
x: 382.567,
|
||||||
const startPos = ref({ x: 0, y: 0 })
|
y: 178.123
|
||||||
const currentRect = ref({ left: 0, top: 0, width: 0, height: 0 })
|
},
|
||||||
const selectionRects = ref([]) // 存储所有框选区域
|
{
|
||||||
const selectedPoints = ref([]) // 存储选中的点位
|
x: 481.567,
|
||||||
const selectedPointsInOrder = ref([]) // 按照框选顺序存储选中的点位
|
y: 238.123
|
||||||
|
|
||||||
// 开始框选
|
|
||||||
const startSelection = (event) => {
|
|
||||||
isSelecting.value = true
|
|
||||||
startPos.value = { x: event.clientX, y: event.clientY }
|
|
||||||
currentRect.value = { left: event.clientX, top: event.clientY, width: 0, height: 0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新框选区域
|
|
||||||
const updateSelection = (event) => {
|
|
||||||
if (isSelecting.value) {
|
|
||||||
currentRect.value = {
|
|
||||||
left: Math.min(startPos.value.x, event.clientX),
|
|
||||||
top: Math.min(startPos.value.y, event.clientY),
|
|
||||||
width: Math.abs(event.clientX - startPos.value.x),
|
|
||||||
height: Math.abs(event.clientY - startPos.value.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 结束框选
|
|
||||||
const endSelection = () => {
|
|
||||||
if (isSelecting.value) {
|
|
||||||
isSelecting.value = false
|
|
||||||
selectionRects.value.push({ ...currentRect.value }) // 保存当前框选区域
|
|
||||||
checkPointsInSelection(currentRect.value) // 检查当前框选区域内的点位
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查点位是否在框选区域内
|
|
||||||
const checkPointsInSelection = (rect) => {
|
|
||||||
points.value.forEach((point) => {
|
|
||||||
if (
|
|
||||||
point.x >= rect.left &&
|
|
||||||
point.x <= rect.left + rect.width &&
|
|
||||||
point.y >= rect.top &&
|
|
||||||
point.y <= rect.top + rect.height &&
|
|
||||||
!selectedPoints.value.includes(point) // 避免重复添加
|
|
||||||
) {
|
|
||||||
selectedPoints.value.push(point)
|
|
||||||
selectedPointsInOrder.value.push(point) // 按照框选顺序添加
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 确认选择
|
|
||||||
const confirmSelection = () => {
|
|
||||||
console.log('Selected Points in Order:', selectedPointsInOrder.value)
|
|
||||||
// 清除框选区域和选中的点位
|
|
||||||
selectionRects.value = []
|
|
||||||
selectedPoints.value = []
|
|
||||||
selectedPointsInOrder.value = []
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
points,
|
|
||||||
isSelecting,
|
|
||||||
selectionRects,
|
|
||||||
selectedPoints,
|
|
||||||
startSelection,
|
|
||||||
updateSelection,
|
|
||||||
endSelection,
|
|
||||||
confirmSelection
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const mapPointsToLine = (points) => {
|
||||||
|
if (points.length < 2) {
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
// 取数组的第一项和最后一项
|
||||||
|
const firstPoint = points[0]
|
||||||
|
const lastPoint = points[points.length - 1]
|
||||||
|
|
||||||
|
// 计算直线的斜率
|
||||||
|
const dx = lastPoint.x - firstPoint.x
|
||||||
|
const dy = lastPoint.y - firstPoint.y
|
||||||
|
if (dx === 0) {
|
||||||
|
// 垂直直线的情况
|
||||||
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
|
return point
|
||||||
|
}
|
||||||
|
return { x: firstPoint.x, y: point.y }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const slope = dy / dx
|
||||||
|
// 计算直线的截距
|
||||||
|
const intercept = firstPoint.y - slope * firstPoint.x
|
||||||
|
|
||||||
|
// 映射其他点到直线上
|
||||||
|
return points.map((point, index) => {
|
||||||
|
if (index === 0 || index === points.length - 1) {
|
||||||
|
return point
|
||||||
|
}
|
||||||
|
const newY = slope * point.x + intercept
|
||||||
|
return { x: point.x, y: newY }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mappedPoints = mapPointsToLine(points.value)
|
||||||
|
console.log(mappedPoints)
|
||||||
</script>
|
</script>
|
||||||
|
@ -551,13 +551,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item
|
<div style="width: 100%; display: flex; align-items: center">
|
||||||
required
|
<el-form-item
|
||||||
label="放货位置"
|
required
|
||||||
:prop="`taskDetailList[${index}].releaseId`"
|
label="放货位置"
|
||||||
:rules="{ required: true, message: '放货位置不能为空', trigger: 'change' }"
|
:prop="`taskDetailList[${index}].releaseId`"
|
||||||
>
|
:rules="{ required: true, message: '放货位置不能为空', trigger: 'change' }"
|
||||||
<div style="width: 100%; display: flex; align-items: center">
|
>
|
||||||
<el-select
|
<el-select
|
||||||
:disabled="!detailItem.releaseType"
|
:disabled="!detailItem.releaseType"
|
||||||
v-model="detailItem.releaseId"
|
v-model="detailItem.releaseId"
|
||||||
@ -579,15 +579,15 @@
|
|||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-icon
|
</el-form-item>
|
||||||
class="ml-2"
|
<el-icon
|
||||||
size="20"
|
class="ml-2"
|
||||||
color="#00329F"
|
size="20"
|
||||||
@click="chooseLocation('release', detailItem, index)"
|
color="#00329F"
|
||||||
><Location />
|
@click="chooseLocation('release', detailItem, index)"
|
||||||
</el-icon>
|
><Location />
|
||||||
</div>
|
</el-icon>
|
||||||
</el-form-item>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
|
Loading…
Reference in New Issue
Block a user