zn-admin-vue3-wcs/src/views/mapPage/realTimeMap/components-tool/editNodeProperties.vue
2025-03-28 14:22:29 +08:00

489 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<Dialog
v-model="dialogFormVisible"
title="节点属性"
width="540"
class="node-form-dialog"
@close="dialogClose"
>
<el-form :model="form" label-width="80" ref="ruleFormRef" :rules="rules">
<el-form-item label="X" prop="locationX" required>
<el-input-number
style="width: 100%"
v-model="form.locationX"
:min="0"
placeholder="请输入"
controls-position="right"
/>
</el-form-item>
<el-form-item label="Y" prop="locationY" required>
<el-input-number
style="width: 100%"
v-model="form.locationY"
:min="0"
placeholder="请输入"
controls-position="right"
/>
</el-form-item>
<el-form-item label="类型" prop="type" required>
<el-select v-model="form.type" placeholder="请选择类型" @change="typeChange">
<el-option label="路径点位" :value="1" />
<el-option label="库位点" :value="2" />
<el-option label="设备点" :value="3" />
<el-option label="停车点" :value="4" />
<el-option label="区域变更点" :value="5" />
<el-option label="等待点" :value="6" />
</el-select>
</el-form-item>
<el-form-item label="弧度" prop="locationYaw" required>
<el-input-number
class="!w-200px"
v-model="form.locationYaw"
:min="0"
:max="10000"
placeholder="请输入"
:precision="2"
/>
</el-form-item>
<div v-if="form.type === 2 || form.type === 3 || form.type === 4">
<el-form-item label="层数" prop="layersNumber" required v-if="form.type === 2">
<el-input-number
class="!w-200px"
v-model="form.layersNumber"
:min="1"
:max="4"
:precision="0"
:step="1"
step-strictly
/>
<el-text class="mx-1">最大层数4</el-text>
</el-form-item>
<el-form-item label="排序" prop="locationNumber" v-if="form.type === 2" required>
<el-input-number class="!w-200px" v-model="form.locationNumber" :min="1" />
<el-text class="mx-1">最大值10000000</el-text>
</el-form-item>
<el-form-item label="编号" prop="deviceId" required v-if="form.type === 3">
<div>
<el-select
v-model="deviceInfo.deviceType"
class="!w-160px"
clearable
placeholder="请选择设备类型"
@change="deviceTypeChange()"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.DEVICE_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
<el-select
v-model="form.deviceId"
class="!w-160px ml-4"
clearable
placeholder="请选择设备编号"
@change="deviceChange"
>
<el-option
:disabled="item.idDisabled"
v-for="item in deviceList"
:key="item.id"
:label="item.deviceNo"
:value="item.id"
/>
</el-select>
</div>
</el-form-item>
<el-form-item label="库位长度" prop="locationDeep" required>
<div style="display: flex">
<el-input-number
class="!w-200px"
placeholder="请输入"
v-model="form.locationDeep"
:min="10"
/>
<span class="ml-2">cm</span>
</div>
</el-form-item>
<el-form-item label="库位宽度" prop="locationWide" required>
<div style="display: flex">
<el-input-number
class="!w-200px"
placeholder="请输入"
v-model="form.locationWide"
:min="10"
/>
<span class="ml-2">cm</span>
</div>
</el-form-item>
<div v-if="form.type === 2 || form.type === 4">
<el-form-item label="库位方向" prop="direction">
<el-select
v-model="form.direction"
placeholder="请选择库位方向"
@change="directionChange"
>
<el-option label="单向" :value="1" />
<el-option label="双向" :value="2" />
<el-option label="三向" :value="3" />
<el-option label="四向" :value="4" />
</el-select>
</el-form-item>
<div v-if="form.direction !== 1">
<el-form-item label="进入方向" prop="inDirection">
<el-select v-model="form.inDirection" placeholder="请选择进入方向">
<el-option label="尾入" :value="0" />
<el-option label="头入" :value="1" />
</el-select>
</el-form-item>
<el-form-item label="离开方向" prop="outDirection">
<el-select v-model="form.outDirection" placeholder="请选择离开方向">
<el-option label="尾出" :value="0" />
<el-option label="头出" :value="1" />
</el-select>
</el-form-item>
</div>
</div>
</div>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="submit(ruleFormRef)"> 确认 </el-button>
</div>
</template>
</Dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as MapApi from '@/api/map/map'
const ruleFormRef = ref()
const dialogFormVisible = ref(false)
const message = useMessage() // 消息弹窗
const props = defineProps({
positionMapId: {
type: String,
default: () => ''
},
imgBgObj: {
type: Object,
default: () => {}
}
})
const form = ref({
type: 1, //类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点
layersNumber: 1, //层数
locationX: undefined, //库位坐标x轴
locationY: undefined, //库位坐标y轴
locationDeep: undefined, //长度
locationWide: undefined, //宽度
direction: undefined, //库位方向1单向、2双向、3三向、4四向
inDirection: undefined, //进入方向0尾入、1头入
outDirection: undefined, //离开方向0尾出、1头出
dataList: [], //存库位的
dataObj: {}, //存 设备点 停车点 文字
positionMapId: undefined,
deviceId: undefined, //设备id
locationYaw: undefined //弧度
})
const mapWidthCm = ref(0)
const mapHeightCm = ref(0)
watch(
() => props.imgBgObj,
(val) => {
mapWidthCm.value = (Number(val.width) * Number(val.resolution) * 100).toFixed(2)
mapHeightCm.value = (Number(val.height) * Number(val.resolution) * 100).toFixed(2)
},
{ immediate: true }
)
const validateNumberLength = (rule, value, callback) => {
if (value.toString().length > 25) {
callback(new Error('输入的数字长度不能超过25位'))
} else {
callback()
}
}
const rules = reactive({
locationX: [
{ 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' }
],
locationY: [
{ 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' }
],
locationYaw: [{ required: true, message: '请输入弧度', trigger: 'blur' }],
type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
layersNumber: [{ required: true, message: '请输入层数', trigger: 'blur' }],
locationNumber: [
{ required: true, message: '请输入排序', trigger: 'blur' },
{
type: 'number',
min: 0,
max: 10000000,
message: `不能超过10000000`,
trigger: 'blur'
}
],
deviceId: [{ required: true, message: '请选择设备编号', trigger: 'blur' }],
locationDeep: [
{ required: true, message: '请选择库位长度', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(mapWidthCm.value),
message: `不能超过${Number(mapWidthCm.value)}cm`,
trigger: 'blur'
}
],
locationWide: [
{ required: true, message: '请选择库位宽度', trigger: 'blur' },
{
type: 'number',
min: 0,
max: Number(mapHeightCm.value),
message: `不能超过${Number(mapHeightCm.value)}cm`,
trigger: 'blur'
}
]
})
const emit = defineEmits(['submitNodeSuccess', 'addEventListener'])
const submit = async (formEl) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (!valid) return
//在这边把数据处理好
if (form.value.type === 1 || form.value.type === 5 || form.value.type === 6) {
//不需要dataJson的类型
form.value.dataJson = ''
} else if (form.value.type === 2) {
//库位点 类型为数组
let list = []
for (let index = 0; index < form.value.layersNumber; index++) {
let item = {
positionMapId: props.positionMapId,
locationWide: form.value.locationWide || undefined,
locationDeep: form.value.locationDeep || undefined,
direction: form.value.direction || undefined, //方向
inDirection: form.value.inDirection || undefined, //进入方向
outDirection: form.value.outDirection || undefined, //离开方向
locationStorey: index + 1 //层数
}
if (
form.value.dataList.length > 0 &&
form.value.dataList[index] &&
form.value.dataList[index].id
) {
item.id = String(form.value.dataList[index].id)
item.locationNo = form.value.dataList[index].locationNo
item.mapItemId = form.value.dataList[index].mapItemId
item.areaId = form.value.dataList[index].areaId || ''
item.areaName = form.value.dataList[index].areaName || ''
item.laneId = form.value.dataList[index].laneId || ''
item.laneName = form.value.dataList[index].laneName || ''
}
list.push(item)
}
form.value.dataList = list
//dataJson数据
form.value.dataJson = JSON.stringify(form.value.dataList)
} else if (form.value.type === 3) {
//设备类型
form.value.dataObj.positionMapId = props.positionMapId
form.value.dataObj.locationWide = form.value.locationWide
form.value.dataObj.locationDeep = form.value.locationDeep
form.value.dataObj.direction = form.value.direction
form.value.dataObj.inDirection = form.value.inDirection
form.value.dataObj.outDirection = form.value.outDirection
form.value.dataObj.id = form.value.deviceId
form.value.dataObj.deviceType = deviceInfo.value.deviceType
form.value.dataObj.deviceNo = deviceInfo.value.deviceNo
form.value.dataObj.mapImageUrl = deviceInfo.value.mapImageUrl
form.value.mapImageUrl = deviceInfo.value.mapImageUrl
//dataJson数据
form.value.dataJson = JSON.stringify(form.value.dataObj)
} else {
//类型为路径点位 区域变更点 等待点 值为对象
form.value.dataObj.positionMapId = props.positionMapId
form.value.dataObj.locationWide = form.value.locationWide
form.value.dataObj.locationDeep = form.value.locationDeep
form.value.dataObj.direction = form.value.direction
form.value.dataObj.inDirection = form.value.inDirection
form.value.dataObj.outDirection = form.value.outDirection
//dataJson数据
form.value.dataJson = JSON.stringify(form.value.dataObj)
}
emit('submitNodeSuccess', form.value)
dialogFormVisible.value = false
})
}
const dialogClose = () => {
emit('addEventListener')
}
const equipmentList = ref([]) //用过的设备列表
const open = (item, list) => {
form.value = item
form.value.layersNumber = item.dataList?.length || ''
form.value.deviceId = item?.deviceId || item?.dataObj?.id || ''
form.value.positionMapId = props.positionMapId
deviceInfo.value.deviceNo = item?.deviceNo || item?.dataObj?.deviceNo || ''
deviceInfo.value.mapImageUrl = item?.mapImageUrl || item?.dataObj?.mapImageUrl || ''
equipmentList.value = list
if (item?.dataObj?.deviceType) {
deviceInfo.value.deviceType = item.dataObj.deviceType || ''
getDeviceList()
} else {
deviceInfo.value.deviceType = ''
}
dialogFormVisible.value = true
}
//类型改变
const typeChange = (type) => {
form.value.dataJson = null
form.value.dataObj = {}
form.value.dataList = []
if (type === 1) {
form.value.layersNumber = null
form.value.direction = null
form.value.inDirection = null
form.value.outDirection = null
form.value.locationNumber = null
form.value.locationDeep = 40
form.value.locationWide = 40
form.value.locationDeepPx = 8
form.value.locationWidePx = 8
} else if (type === 2) {
form.value.locationNumber = null
form.value.locationDeep = 150
form.value.locationWide = 150
form.value.locationDeepPx = 30
form.value.locationWidePx = 30
} else if (type === 3) {
form.value.direction = null
form.value.inDirection = null
form.value.outDirection = null
form.value.locationNumber = null
form.value.locationDeep = 150
form.value.locationWide = 150
form.value.locationDeepPx = 30
form.value.locationWidePx = 30
} else if (type === 4) {
form.value.direction = null
form.value.inDirection = null
form.value.outDirection = null
form.value.locationNumber = null
form.value.locationDeep = 150
form.value.locationWide = 150
form.value.locationDeepPx = 30
form.value.locationWidePx = 30
} else if (type === 5) {
form.value.layersNumber = null
form.value.direction = null
form.value.inDirection = null
form.value.outDirection = null
form.value.locationNumber = null
form.value.locationDeep = 150
form.value.locationWide = 150
form.value.locationDeepPx = 30
form.value.locationWidePx = 30
} else if (type === 6) {
form.value.layersNumber = null
form.value.direction = null
form.value.inDirection = null
form.value.outDirection = null
form.value.locationNumber = null
form.value.locationDeep = 150
form.value.locationWide = 150
form.value.locationDeepPx = 30
form.value.locationWidePx = 30
}
}
//设备切换
const deviceChange = (deviceId) => {
deviceList.value.forEach((item) => {
if (item.id == deviceId) {
deviceInfo.value.mapImageUrl = item.mapImageUrl
deviceInfo.value.deviceNo = item.deviceNo
}
})
}
//方向改变
const directionChange = (e) => {
if (e === 1) {
form.value.inDirection = undefined
form.value.outDirection = undefined
}
}
//设备信息
const deviceInfo = ref({
positionMapId: '',
deviceType: '',
mapImageUrl: '',
deviceNo: ''
})
//设备列表
const deviceList = ref([])
//获取设备列表
const getDeviceList = async () => {
deviceInfo.value.positionMapId = props.positionMapId
let list = await MapApi.getDeviceInformationList(deviceInfo.value)
const deviceIds = equipmentList.value.map((item) => item.deviceId)
deviceList.value = list.map((item) => {
return {
...item,
idDisabled: deviceIds.includes(item.id)
}
})
}
//设备类型切换
const deviceTypeChange = () => {
form.value.deviceId = ''
getDeviceList()
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
</script>
<style lang="scss">
.node-form-dialog {
.el-dialog__header {
border-bottom: none;
}
.el-dialog__footer {
border-top: none !important;
}
}
</style>