zn-admin-vue3-wcs/src/views/mapPage/realTimeMap/components-tool/editMapRouteDialog.vue
2025-04-09 14:58:09 +08:00

532 lines
18 KiB
Vue

<template>
<!-- 新增设备 -->
<Dialog
v-model="dialogFormVisible"
title="编辑路线"
width="840"
class="map-edit-route-dialog"
@close="dialogClose"
>
<el-form :model="form" label-width="130" ref="ruleFormRef" :rules="rules">
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="开始点位序号" prop="startingSortNum">
<el-input
style="width: 100%"
v-model="form.startingSortNum"
:min="0"
:disabled="true"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束点位序号" prop="endPointSortNum">
<el-input
style="width: 100%"
v-model="form.endPointSortNum"
:min="0"
:disabled="true"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="开始点位x轴" prop="startPointX" required>
<el-input-number
style="width: 100%"
v-model="form.startPointX"
:min="0"
placeholder="请输入开始点位x轴"
controls-position="right"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开始点位y轴" prop="startPointY" required>
<el-input-number
style="width: 100%"
v-model="form.startPointY"
:min="0"
placeholder="请输入开始点位y轴"
controls-position="right"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="结束点位x轴" prop="endPointX" required>
<el-input-number
style="width: 100%"
v-model="form.endPointX"
:min="0"
placeholder="请输入结束点位x轴"
controls-position="right"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="结束点位y轴" prop="endPointY" required>
<el-input-number
style="width: 100%"
v-model="form.endPointY"
:min="0"
placeholder="请输入结束点位y轴"
controls-position="right"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="开始控制点x轴" prop="beginControlX" required>
<el-input v-model="form.beginControlX" type="number" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="开始控制点y轴" prop="beginControlY" required>
<el-input v-model="form.beginControlY" type="number" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="结束控制点x轴" prop="endControlX" required>
<el-input v-model="form.endControlX" type="number" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label=" 结束控制点y轴" prop="endControlY" required>
<el-input v-model="form.endControlY" type="number" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="膨胀区域前" prop="expansionZoneFront" required>
<el-input v-model="form.expansionZoneFront" type="number">
<template #append>米</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="膨胀区域后" prop="expansionZoneAfter" required>
<el-input v-model="form.expansionZoneAfter" type="number">
<template #append>米</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="膨胀区域左" prop="expansionZoneLeft" required>
<el-input v-model="form.expansionZoneLeft" type="number">
<template #append>米</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="膨胀区域右" prop="expansionZoneRight" required>
<el-input v-model="form.expansionZoneRight" type="number">
<template #append>米</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="正向限速" prop="forwardSpeedLimit" required>
<div class="flex-center">
<el-slider v-model="form.forwardSpeedLimit" :min="0.1" :max="10" :step="0.1" />
<el-input
v-model="form.forwardSpeedLimit"
style="width: 200px; margin-left: 6px"
type="number"
:min="0.1"
:max="10"
:disabled="true"
>
<template #append>m/s</template>
</el-input>
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="反向限速" prop="reverseSpeedLimit" required>
<div class="flex-center">
<el-slider v-model="form.reverseSpeedLimit" :min="0.1" :max="10" :step="0.1" />
<el-input
v-model="form.reverseSpeedLimit"
style="width: 200px; margin-left: 6px"
type="number"
:min="0.1"
:max="10"
:disabled="true"
>
<template #append>m/s</template>
</el-input>
</div>
</el-form-item></el-col
>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
<el-form-item label="行走方法" prop="method" required>
<el-select v-model="form.method" placeholder="请选择行走方法" @change="methodChange">
<el-option label="直线" :value="0" />
<el-option label="曲线" :value="1" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="方向" prop="direction" required>
<el-select v-model="form.direction" placeholder="请选择方向">
<el-option label="单向" :value="1" />
<el-option label="双向" :value="2" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<!-- 单向 -->
<el-col :span="12" v-if="form.direction === 1">
<el-form-item label="车头朝向" prop="toward" required>
<el-select v-model="form.toward" placeholder="请选择车头朝向">
<el-option
v-for="(item, index) in towardList"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.direction === 2">
<el-form-item
:label="
'开始点' + (form.startingSortNum || '') + '到结束点' + (form.endPointSortNum || '')
"
prop="startToEndToward"
required
label-width="180"
>
<el-select v-model="form.startToEndToward" placeholder="请选择车头朝向">
<el-option
v-for="(item, index) in towardList"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.direction === 2">
<el-form-item
:label="
'结束点' + (form.endPointSortNum || '') + '到开始点' + (form.startingSortNum || '')
"
prop="endToStartToward"
required
label-width="180"
>
<el-select v-model="form.endToStartToward" placeholder="请选择车头朝向">
<el-option
v-for="(item, index) in towardList"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</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 props = defineProps({
imgBgObj: {
type: Object,
default: () => {}
}
})
const ruleFormRef = ref()
const dialogFormVisible = ref(false) //列表的
const validateNumberLength = (rule, value, callback) => {
if (value.toString().length > 25) {
callback(new Error('输入的数字长度不能超过25位'))
} else {
callback()
}
}
const rules = reactive({
startPointX: [
{ required: true, message: '请输入开始点位x轴坐标', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(props.imgBgObj.width),
message: `不能超过地图宽度${props.imgBgObj.width}`,
trigger: 'blur'
},
{ validator: validateNumberLength, trigger: 'blur' }
],
startPointY: [
{ required: true, message: '请输入开始点位y轴坐标', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(props.imgBgObj.height),
message: `不能超过地图宽度${props.imgBgObj.height}`,
trigger: 'blur'
},
{ validator: validateNumberLength, trigger: 'blur' }
],
endPointX: [
{ required: true, message: '请输入结束点位x轴坐标', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(props.imgBgObj.width),
message: `不能超过地图宽度${props.imgBgObj.width}`,
trigger: 'blur'
},
{ validator: validateNumberLength, trigger: 'blur' }
],
endPointY: [
{ required: true, message: '请输入结束点位y轴坐标', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(props.imgBgObj.height),
message: `不能超过地图宽度${props.imgBgObj.height}`,
trigger: 'blur'
},
{ validator: validateNumberLength, trigger: 'blur' }
],
expansionZoneFront: [{ required: true, message: '请输入膨胀区域前', trigger: 'blur' }],
expansionZoneAfter: [{ required: true, message: '请输入膨胀区域后', trigger: 'blur' }],
expansionZoneLeft: [{ required: true, message: '请输入膨胀区域左', trigger: 'blur' }],
expansionZoneRight: [{ required: true, message: '请输入膨胀区域右', trigger: 'blur' }]
})
//新增
const form = ref({
positionMapId: '',
startPointX: '', // 开始点位x轴
startPointY: '', // 开始点位y轴
endPointX: '', // 结束点位x轴
endPointY: '', // 结束点位y轴
expansionZoneFront: 0, //膨胀区域前
expansionZoneAfter: 0, //膨胀区域后
expansionZoneLeft: 0, // 膨胀区域左
expansionZoneRight: 0, //膨胀区域右
method: 0, // 行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线
direction: 2, //方向 1.单向 2.双向
forwardSpeedLimit: 1.5, //正向限速
reverseSpeedLimit: 0.4, // 反向限速
toward: 0, //车头朝向(0:正正 1:正反 2:反正 3:反反 4正随 5随正 6随反 7反随 8随随 如果是单向的话 0代表正 1代表反 2代表随意
startToEndToward: 0, //开始点到结束点车头朝向
endToStartToward: 0 //结束点到开始点车头朝向
})
const open = (item) => {
dialogFormVisible.value = true
form.value = item
if (form.value.direction == 2) {
//双向
if (item.toward === 0) {
//正正
form.value.startToEndToward = 0
form.value.endToStartToward = 0
} else if (item.toward === 1) {
//正反
form.value.startToEndToward = 0
form.value.endToStartToward = 1
} else if (item.toward === 2) {
//反正
form.value.startToEndToward = 1
form.value.endToStartToward = 0
} else if (item.toward === 3) {
//反反
form.value.startToEndToward = 1
form.value.endToStartToward = 1
} else if (item.toward === 4) {
// 4正随
form.value.startToEndToward = 0
form.value.endToStartToward = 2
} else if (item.toward === 5) {
//5随正
form.value.startToEndToward = 2
form.value.endToStartToward = 0
} else if (item.toward === 6) {
//6随反
form.value.startToEndToward = 2
form.value.endToStartToward = 1
} else if (item.toward === 7) {
//7反随
form.value.startToEndToward = 1
form.value.endToStartToward = 2
} else if (item.toward === 8) {
//8随随
form.value.startToEndToward = 2
form.value.endToStartToward = 2
}
}
}
const dialogClose = () => {
emit('addEventListener')
}
const emit = defineEmits(['editMapRouteDialogSubmit', 'addEventListener'])
const submitForm = async (formEl) => {
if (!formEl) return
await checkToward()
await formEl.validate(async (valid, fields) => {
if (valid) {
let actualStartPoint = disposeEventPoint(form.value.startPointX, form.value.startPointY)
let actualEndPoint = disposeEventPoint(form.value.endPointX, form.value.endPointY)
form.value.actualStartPointX = actualStartPoint.actualLocationX //实际开始点位x轴
form.value.actualStartPointY = actualStartPoint.actualLocationY //实际开始点位y轴
form.value.actualEndPointX = actualEndPoint.actualLocationX //实际结束点位x轴
form.value.actualEndPointY = actualEndPoint.actualLocationY //实际结束点位y轴
if (form.value.method === 1) {
let actualBeginControl = disposeEventPoint(
form.value.beginControlX,
form.value.beginControlY
)
let actualEndControl = disposeEventPoint(form.value.endControlX, form.value.endControlY)
form.value.actualBeginControlX = actualBeginControl.actualLocationX //实际开始控制点x轴
form.value.actualBeginControlY = actualBeginControl.actualLocationY //实际开始控制点y轴
form.value.actualEndControlX = actualEndControl.actualLocationX //实际结束控制点x轴
form.value.actualEndControlY = actualEndControl.actualLocationY //实际结束控制点y轴
} else {
form.value.beginControlX = 0
form.value.beginControlY = 0
form.value.endControlX = 0
form.value.endControlY = 0
form.value.actualBeginControlX = 0
form.value.actualBeginControlY = 0
form.value.actualEndControlX = 0
form.value.actualEndControlY = 0
}
emit('editMapRouteDialogSubmit', form.value)
dialogFormVisible.value = false
}
})
}
const methodChange = (e) => {
if (e === 0) {
form.value.beginControlX = 0
form.value.beginControlY = 0
form.value.endControlX = 0
form.value.endControlY = 0
} else {
form.value.beginControlX = Number(form.value.startPointX) + 50 //开始控制点x轴
form.value.beginControlY = Number(form.value.startPointY) + 50 //开始控制点y轴
form.value.endControlX = Number(form.value.endPointX) - 50 //结束控制点x轴
form.value.endControlY = Number(form.value.endPointY) - 50 //结束控制点y轴
}
}
const checkToward = () => {
//如果是双向
if (form.value.direction !== 2) return
//车头朝向(0:正正 1:正反 2:反正 3:反反 4正随 5随正 6随反 7反随 8随随
if (form.value.startToEndToward === 0 && form.value.endToStartToward === 0) {
form.value.toward = 0
} else if (form.value.startToEndToward === 0 && form.value.endToStartToward === 1) {
form.value.toward = 1
} else if (form.value.startToEndToward === 1 && form.value.endToStartToward === 0) {
form.value.toward = 2
} else if (form.value.startToEndToward === 1 && form.value.endToStartToward === 1) {
form.value.toward = 3
} else if (form.value.startToEndToward === 0 && form.value.endToStartToward === 2) {
form.value.toward = 4
} else if (form.value.startToEndToward === 2 && form.value.endToStartToward === 0) {
form.value.toward = 5
} else if (form.value.startToEndToward === 2 && form.value.endToStartToward === 1) {
form.value.toward = 6
} else if (form.value.startToEndToward === 1 && form.value.endToStartToward === 2) {
form.value.toward = 7
} else if (form.value.startToEndToward === 2 && form.value.endToStartToward === 2) {
form.value.toward = 8
}
}
//方向改变
const towardList = ref([
{
value: 0,
label: '前进'
},
{
value: 1,
label: '倒车'
},
{
value: 2,
label: '不限制方向'
}
])
//传入x y轴坐标
const disposeEventPoint = (x, y) => {
const actualLocationX =
Number(props.imgBgObj.origin[0]) + Number(x) * Number(props.imgBgObj.resolution)
const actualLocationY =
Number(props.imgBgObj.origin[1]) +
(Number(props.imgBgObj.height) - Number(y)) * Number(props.imgBgObj.resolution)
return {
actualLocationX,
actualLocationY
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
</script>
<style lang="scss">
.map-edit-route-dialog {
padding: 0px;
.el-dialog__footer {
padding: 0px 20px 20px 0;
border-top: none !important;
}
}
.el-input-group__append,
.el-input-group__prepend {
padding: 0 8px;
}
.flex-center {
width: 100%;
display: flex;
align-items: center;
}
</style>