生成直角拐点改为后端定义变量值,根据贝塞尔曲线的偏移量动态改变弧度
增加等距复制点的弹窗
This commit is contained in:
parent
cd17472173
commit
709df94ff3
@ -7,7 +7,17 @@
|
||||
class="batch-copying-dialog-form"
|
||||
@close="dialogClose"
|
||||
>
|
||||
<el-form :model="batchCopyingForm" label-width="120" ref="BatchCopyingFormRef" :rules="rules">
|
||||
<el-form :model="batchCopyingForm" label-width="110" ref="BatchCopyingFormRef" :rules="rules">
|
||||
<el-form-item label="偏移距离(米)" prop="distance" required>
|
||||
<el-input-number
|
||||
v-model="batchCopyingForm.distance"
|
||||
placeholder="请输入距离"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
:min="0"
|
||||
precision="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="方向(弧度)" prop="radian" required>
|
||||
<el-input-number
|
||||
v-model="batchCopyingForm.radian"
|
||||
@ -20,16 +30,20 @@
|
||||
precision="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="偏移距离(米)" prop="distance" required>
|
||||
<el-input-number
|
||||
v-model="batchCopyingForm.distance"
|
||||
placeholder="请输入距离"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
:min="0"
|
||||
precision="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div class="tips">
|
||||
<div class="mb-1">
|
||||
<el-text>向上:弧度 1.57079</el-text>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向左:弧度 3.141592</el-text>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向下:弧度 -1.57079</el-text>
|
||||
</div>
|
||||
<div class="mb-1">
|
||||
<el-text>向右:弧度 0</el-text>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
@ -127,5 +141,9 @@ defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
padding: 0px 20px 20px 0;
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.tips {
|
||||
padding-left: 110px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<!-- 新增设备 -->
|
||||
<Dialog
|
||||
v-model="dialogFormVisible"
|
||||
title="等距复制"
|
||||
width="540"
|
||||
class="isometric-replication-dialog"
|
||||
@close="dialogClose"
|
||||
>
|
||||
<el-form :model="form" label-width="110" ref="ruleFormRef" :rules="rules">
|
||||
<el-form-item label="间隔距离/米" prop="distance" required>
|
||||
<el-input-number
|
||||
v-model="form.distance"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="复制数量" prop="number" required>
|
||||
<el-input-number
|
||||
v-model="form.number"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="复制角度" prop="angle" required>
|
||||
<el-input-number
|
||||
v-model="form.angle"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
placeholder="请输入"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)"> 确定 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
const ruleFormRef = ref()
|
||||
const dialogFormVisible = ref(false) //列表的
|
||||
|
||||
const rules = reactive({
|
||||
distance: [{ required: true, message: '请输入间隔距离', trigger: 'blur' }],
|
||||
number: [{ required: true, message: '请输入复制数量', trigger: 'blur' }],
|
||||
angle: [{ required: true, message: '请输入复制角度', trigger: 'blur' }]
|
||||
})
|
||||
|
||||
//新增
|
||||
const form = ref({
|
||||
positionMapId: '',
|
||||
skuInfo: '', //物料信息
|
||||
areaName: '', //物料区域名称
|
||||
areaNumber: 0,
|
||||
mapItemIds: []
|
||||
})
|
||||
|
||||
const open = (list) => {
|
||||
dialogFormVisible.value = true
|
||||
}
|
||||
|
||||
const emit = defineEmits(['addEventListener', 'itemAreaSettingSubmitSuccess'])
|
||||
const dialogClose = () => {
|
||||
emit('addEventListener')
|
||||
}
|
||||
|
||||
const submitForm = async (formEl) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate(async (valid, fields) => {
|
||||
if (valid) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.isometric-replication-dialog {
|
||||
padding: 0px;
|
||||
|
||||
.el-dialog__footer {
|
||||
padding: 0px 20px 20px 0;
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -966,6 +966,12 @@
|
||||
:imgBgObj="imgBgObj"
|
||||
@submit-batch-copying-form-success="submitBatchCopyingFormSuccess"
|
||||
/>
|
||||
<!-- 等距复制 -->
|
||||
<IsometricReplicationDialog
|
||||
ref="IsometricReplicationDialogRef"
|
||||
@add-event-listener="addEventListener"
|
||||
/>
|
||||
|
||||
<!-- 节点右击菜单 -->
|
||||
<div
|
||||
v-if="state.contextMenu.visible"
|
||||
@ -975,6 +981,7 @@
|
||||
>
|
||||
<div class="context-menu-item" @click="deleteSingleNode">删除</div>
|
||||
<div class="context-menu-item" @click="contextMenuEditNode">编辑节点</div>
|
||||
<div class="context-menu-item" @click="isometricReplication">等距复制</div>
|
||||
<div
|
||||
class="context-menu-item"
|
||||
@click="generateDetectionPoint"
|
||||
@ -1016,6 +1023,7 @@ import BatchCopyingDialogForm from './components-tool/BatchCopyingDialogForm.vue
|
||||
import lineLibrarySettingDialog from './components-tool/lineLibrarySettingDialog.vue'
|
||||
import layerSelectionToolDialog from './components-tool/layerSelectionToolDialog.vue'
|
||||
import itemAreaManagementDialog from './components-tool/itemAreaManagementDialog.vue'
|
||||
import IsometricReplicationDialog from './components-tool/IsometricReplicationDialog.vue'
|
||||
import lineLibraryManagementDialog from './components-tool/lineLibraryManagementDialog.vue'
|
||||
import GenerateStraightLinesDialog from './components-tool/GenerateStraightLinesDialog.vue'
|
||||
import mapScaleTool from './components-tool/map-scale-tool.vue'
|
||||
@ -1028,6 +1036,7 @@ defineOptions({ name: 'EditMapPageRealTimeMap' })
|
||||
|
||||
const GenerateStraightLinesDialogRef = ref() //生成直线的
|
||||
const lineLibraryManagementDialogRef = ref() //线库管理
|
||||
const IsometricReplicationDialogRef = ref() //等距离复制
|
||||
const itemAreaManagementDialogRef = ref() //区域管理
|
||||
const lineLibrarySettingDialogRef = ref() //线库设置
|
||||
const itemAreaSettingDialogRef = ref() //物料区域设置
|
||||
@ -1775,7 +1784,9 @@ const state = reactive({
|
||||
y: 0,
|
||||
currentCurve: null,
|
||||
currentIndex: -1
|
||||
}
|
||||
},
|
||||
checkPointDistance: 0,
|
||||
curveOffsetValue: 0
|
||||
})
|
||||
|
||||
const getRefLineParams = (params) => {
|
||||
@ -2194,6 +2205,13 @@ const contextMenuEditNode = () => {
|
||||
}
|
||||
}
|
||||
|
||||
//等距复制
|
||||
const isometricReplication = () => {
|
||||
// IsometricReplicationDialogRef.value.open()
|
||||
// hideContextMenu()
|
||||
message.warning('规则暂未制定')
|
||||
}
|
||||
|
||||
//生成检测点
|
||||
const generateDetectionPoint = async () => {
|
||||
if (state.contextMenu.currentIndex === -1) return
|
||||
@ -2205,8 +2223,7 @@ const generateDetectionPoint = async () => {
|
||||
state.contextMenu.currentItem
|
||||
|
||||
const newId = await MapApi.getNodeId()
|
||||
const distance = await MapApi.getCheckDistance()
|
||||
const distanceValue = Number(distance) / Number(imgBgObj.resolution) //距离米
|
||||
const distanceValue = Number(state.checkPointDistance) / Number(imgBgObj.resolution) //距离米
|
||||
|
||||
// 将弧度转换为角度(用于理解,实际计算仍使用弧度)
|
||||
const angle = locationYaw * (180 / Math.PI)
|
||||
@ -3962,6 +3979,14 @@ const saveNodeList = async () => {
|
||||
throw new Error('节点保存失败:' + (error?.message || '未知错误'))
|
||||
}
|
||||
}
|
||||
|
||||
//获取配置数据
|
||||
const getCheckDistance = async () => {
|
||||
const res = await MapApi.getCheckDistance()
|
||||
state.checkPointDistance = Number(res.mapCheckDistance)
|
||||
state.curveOffsetValue = Number(res.mapArcOffset)
|
||||
}
|
||||
|
||||
//路线的保存
|
||||
const saveMapRoute = async () => {
|
||||
try {
|
||||
@ -4289,6 +4314,7 @@ onBeforeRouteLeave((to, from) => {
|
||||
|
||||
onMounted(() => {
|
||||
getMapList()
|
||||
getCheckDistance()
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
})
|
||||
|
||||
@ -4420,8 +4446,9 @@ window.addEventListener('click', (e) => {
|
||||
})
|
||||
|
||||
// 直角拐角控制点计算
|
||||
function getRightAngleControlPoints(direction, start, end, offset = 0) {
|
||||
function getRightAngleControlPoints(direction, start, end) {
|
||||
let corner
|
||||
let offset = -state.curveOffsetValue || 0
|
||||
if (direction === 'leftTop') {
|
||||
corner = { x: Math.min(start.x, end.x), y: Math.min(start.y, end.y) }
|
||||
} else if (direction === 'rightBottom') {
|
||||
@ -4440,11 +4467,21 @@ function getRightAngleControlPoints(direction, start, end, offset = 0) {
|
||||
const len = Math.sqrt(dx * dx + dy * dy) || 1
|
||||
return { x: dx / len, y: dy / len }
|
||||
}
|
||||
// 控制点分别在拐点往起点/终点方向各偏移offset像素
|
||||
// 计算起点终点距离
|
||||
const distance = Math.sqrt((start.x - end.x) ** 2 + (start.y - end.y) ** 2) || 1
|
||||
// 归一化offset,标准距离为100像素
|
||||
const normalizedOffset = offset * (distance / 100)
|
||||
// 控制点分别在拐点往起点/终点方向各偏移normalizedOffset像素
|
||||
const u1 = getUnit(corner, start)
|
||||
const u2 = getUnit(corner, end)
|
||||
const beginControl = { x: corner.x + u1.x * offset, y: corner.y + u1.y * offset }
|
||||
const endControl = { x: corner.x + u2.x * offset, y: corner.y + u2.y * offset }
|
||||
const beginControl = {
|
||||
x: corner.x + u1.x * normalizedOffset,
|
||||
y: corner.y + u1.y * normalizedOffset
|
||||
}
|
||||
const endControl = {
|
||||
x: corner.x + u2.x * normalizedOffset,
|
||||
y: corner.y + u2.y * normalizedOffset
|
||||
}
|
||||
return { beginControl, endControl }
|
||||
}
|
||||
// 设置曲线为直角拐角
|
||||
|
Loading…
Reference in New Issue
Block a user