zn-admin-vue3-wcs/src/views/mapPage/components/locationSelectionDialog.vue

316 lines
9.6 KiB
Vue

<template>
<Dialog
v-model="dialogFormVisible"
title="库区选择"
width="1200"
class="location-selection-dialog"
:fullscreen="false"
top="4vh"
>
<div class="location-selection-dialog-map">
<div
class="location-selection-map"
:style="{
width: imgBgObj.showWidth + 'px',
height: imgBgObj.showHeight + 'px',
backgroundImage: `url(${imgBgObj.imgUrl})`
}"
>
<div
v-for="(item, index) in allMapPointInfo"
:key="index"
class="location-selection-map-item"
>
<template v-if="locationTypeNumber == 1">
<el-popover placement="top" trigger="click" :popper-style="{ padding: '0px' }">
<template #reference>
<img
src="https://api.znkjfw.com/admin-api/infra/file/4/get/库位库存_png_179_1739326653035.png"
alt=""
:style="{
position: 'absolute',
left: Number(item.locationX) - Number(item.locationWidePx) / 2 + 'px',
top: Number(item.locationY) - Number(item.locationDeepPx) / 2 + 'px',
width: item.locationWidePx + 'px',
height: item.locationDeepPx + 'px',
zIndex: 999
}"
/>
</template>
<div class="drop-down-menu">
<!-- 楼层展开 -->
<div
v-for="(floor, floorIndex) in item.dataList"
:key="floorIndex"
class="drop-down-menu-item"
:class="currentItem && currentItem.id == floor.id ? 'tool-active' : ''"
@click="choosePoint(floor)"
>
{{ floor.locationNo }}
</div>
</div>
</el-popover>
</template>
<template v-else>
<el-popover placement="top" trigger="click" :popper-style="{ padding: '0px' }">
<template #reference>
<img
@click="choosePoint(item)"
src="https://api.znkjfw.com/admin-api/infra/file/4/get/库位库存_png_179_1739326653035.png"
alt=""
:style="{
position: 'absolute',
left: Number(item.locationX) - Number(item.locationWidePx) / 2 + 'px',
top: Number(item.locationY) - Number(item.locationDeepPx) / 2 + 'px',
width: item.locationWidePx + 'px',
height: item.locationDeepPx + 'px',
zIndex: 999,
border:
(currentItem &&
locationTypeNumber == 2 &&
currentItem.laneId == item.laneId) ||
(locationTypeNumber == 3 && currentItem.areaId == item.areaId)
? '1px dashed #000'
: 'none'
}"
/>
</template>
<div class="drop-down-menu">
<div class="drop-down-menu" v-if="locationTypeNumber == 2">
<div class="drop-down-menu-item"> {{ item.laneName }} </div>
</div>
<div class="drop-down-menu" v-if="locationTypeNumber == 3">
<div class="drop-down-menu-item">{{ item.areaName }}</div>
</div>
</div>
</el-popover>
</template>
</div>
</div>
</div>
<div class="location-selection-dialog-footer">
<el-button style="width: 90px" @click="dialogFormVisible = false">取消</el-button>
<el-button style="width: 90px" type="primary" @click="submitAddForm"> 确定 </el-button>
</div>
</Dialog>
</template>
<script setup>
import JSONBigInt from 'json-bigint'
import { reactive, ref } from 'vue'
import * as MapApi from '@/api/map/map'
const dialogFormVisible = ref(false) //列表的
const message = useMessage() // 消息弹窗
const props = defineProps({
positionMapId: {
type: String,
default: () => ''
}
})
const locationTypeNumber = ref(1)
const open = (locationTypeNum) => {
dialogFormVisible.value = true
currentItem.value = null
locationTypeNumber.value = locationTypeNum
imgBgObj.positionMapId = props.positionMapId
getMapList()
}
const allMapPointInfo = ref([]) //点位信息
const imgBgObj = reactive({
imgUrl: '',
positionMapId: '',
width: '',
height: '',
floor: '',
area: '',
resolution: 0,
origin: null,
showWidth: 1150,
showHeight: 0
})
const getMapList = async () => {
if (props.positionMapId) {
let res = await MapApi.getPositionMap(props.positionMapId)
let yamlJson = JSON.parse(res.yamlJson)
imgBgObj.positionMapId = res.id
imgBgObj.floor = res.floor
imgBgObj.area = res.area
imgBgObj.width = yamlJson.width
imgBgObj.height = yamlJson.height
imgBgObj.origin = yamlJson.origin
imgBgObj.resolution = yamlJson.resolution
imgBgObj.showHeight = (imgBgObj.showWidth * imgBgObj.height) / imgBgObj.width
} else {
}
getMapData()
getAllNodeList()
}
//调转换成png的接口
const getMapData = async () => {
let data = await MapApi.getPositionMapdDwnloadPngBase64({
floor: imgBgObj.floor,
area: imgBgObj.area
})
imgBgObj.imgUrl = data
}
const currentItem = ref(null)
const getAllNodeList = async () => {
let list = await MapApi.getPositionMapItemList({
positionMapId: imgBgObj.positionMapId
})
allMapPointInfo.value = []
list.forEach((item) => {
//只要库位
if (locationTypeNumber.value == 1 && item.type === 2) {
item.locationX = Number(item.locationX) * (imgBgObj.showWidth / imgBgObj.width)
item.locationY = Number(item.locationY) * (imgBgObj.showWidth / imgBgObj.width)
item.dataList = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
item.locationDeep = item.dataList[0].locationDeep
item.locationWide = item.dataList[0].locationWide
//要将实际的cm改成px
if (item.locationWide && item.locationDeep) {
let pxObj = cmConversionPx(item.locationWide, item.locationDeep)
item.locationWidePx = pxObj.pWidth
item.locationDeepPx = pxObj.pHeight
}
allMapPointInfo.value.push(item)
}
//线库 laneId
if (locationTypeNumber.value == 2 && item.laneId !== null) {
item.locationX = Number(item.locationX) * (imgBgObj.showWidth / imgBgObj.width)
item.locationY = Number(item.locationY) * (imgBgObj.showWidth / imgBgObj.width)
item.dataList = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
item.locationDeep = item.dataList[0].locationDeep
item.locationWide = item.dataList[0].locationWide
item.laneName = item.dataList[0].laneName
//要将实际的cm改成px
if (item.locationWide && item.locationDeep) {
let pxObj = cmConversionPx(item.locationWide, item.locationDeep)
item.locationWidePx = pxObj.pWidth
item.locationDeepPx = pxObj.pHeight
}
allMapPointInfo.value.push(item)
}
//区域 areaId
if (locationTypeNumber.value == 3 && item.areaId !== null) {
item.locationX = Number(item.locationX) * (imgBgObj.showWidth / imgBgObj.width)
item.locationY = Number(item.locationY) * (imgBgObj.showWidth / imgBgObj.width)
item.dataList = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
item.locationDeep = item.dataList[0].locationDeep
item.locationWide = item.dataList[0].locationWide
item.areaName = item.dataList[0].areaName
//要将实际的cm改成px
if (item.locationWide && item.locationDeep) {
let pxObj = cmConversionPx(item.locationWide, item.locationDeep)
item.locationWidePx = pxObj.pWidth
item.locationDeepPx = pxObj.pHeight
}
allMapPointInfo.value.push(item)
}
})
}
//将节点实际宽高cm转换成px
const cmConversionPx = (cWidth, cHeight) => {
let pWidth = (Number(cWidth) / imgBgObj.resolution / 100) * (imgBgObj.showWidth / imgBgObj.width)
let pHeight =
(Number(cHeight) / imgBgObj.resolution / 100) * (imgBgObj.showWidth / imgBgObj.width)
return {
pWidth,
pHeight
}
}
const choosePoint = (item) => {
currentItem.value = item
}
const submitAddForm = () => {
if (currentItem.value) {
emit('locationSelectionDialogSuccess', currentItem.value)
dialogFormVisible.value = false
} else {
message.warning('请选择一个位置')
}
}
const emit = defineEmits(['locationSelectionDialogSuccess'])
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
</script>
<style lang="scss">
.location-selection-dialog {
padding: 0px;
position: relative;
.el-dialog__footer {
padding: 10px 20px 20px 0;
border-top: none !important;
}
.location-selection-dialog-map {
position: relative;
width: 100%;
height: 80vh;
overflow: auto;
.location-selection-map {
position: relative;
width: 100%;
.location-selection-map-item {
position: absolute;
top: 0;
left: 0;
}
}
}
.location-selection-dialog-footer {
position: absolute;
bottom: 30px;
right: 60px;
}
}
.drop-down-menu {
.drop-down-menu-item {
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
padding: 11px 0;
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
color: #0d162a;
line-height: 20px;
text-align: left;
font-style: normal;
border-bottom: 1px solid #e9e9e9;
}
:last-child {
border-bottom: none;
}
}
.tool-active {
background: #ebf1ff !important;
}
</style>