1414 lines
41 KiB
Vue
1414 lines
41 KiB
Vue
<template>
|
||
<div class="top-tool">
|
||
<div class="top-tool-list">
|
||
<div v-for="item in state.topToolList" :key="item.switchType" class="top-tool-item">
|
||
<el-popover
|
||
placement="bottom"
|
||
:width="80"
|
||
trigger="click"
|
||
v-if="item.switchType === 'move' || item.switchType === 'revolve'"
|
||
:disabled="currentItemIndex === -1"
|
||
>
|
||
<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.moveForm" v-if="item.switchType === 'move'">
|
||
<el-form-item label="X">
|
||
<el-input v-model="state.moveForm.locationX" placeholder="请输入" />
|
||
</el-form-item>
|
||
<el-form-item label="Y">
|
||
<el-input v-model="state.moveForm.y" placeholder="请输入" />
|
||
</el-form-item>
|
||
<div style="text-align: right">
|
||
<el-button size="small" color="#00329F" @click="moveFormSubmit">确认</el-button>
|
||
</div>
|
||
</el-form>
|
||
<!-- 旋转 -->
|
||
<el-form :model="state.rotationForm" v-if="item.switchType === 'revolve'">
|
||
<el-form-item label="角度">
|
||
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
|
||
</el-form-item>
|
||
<div style="text-align: right">
|
||
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
|
||
</div>
|
||
</el-form>
|
||
<!-- 字体 -->
|
||
<el-form :model="state.rotationForm" v-if="item.switchType === 'text'">
|
||
<el-form-item label="角度">
|
||
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
|
||
</el-form-item>
|
||
<div style="text-align: right">
|
||
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
|
||
</div>
|
||
</el-form>
|
||
</el-popover>
|
||
|
||
<div
|
||
v-else
|
||
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>
|
||
<!-- 分隔线 -->
|
||
<div
|
||
class="line"
|
||
v-if="
|
||
item.switchType === 'saveAs' ||
|
||
item.switchType === 'delete' ||
|
||
item.switchType === 'grid' ||
|
||
(item.switchType === 'next' &&
|
||
(toolbarSwitchType === 'lineLibrary' || toolbarSwitchType === 'region'))
|
||
"
|
||
></div>
|
||
<el-button
|
||
v-if="
|
||
item.switchType === 'next' &&
|
||
(toolbarSwitchType === 'lineLibrary' || toolbarSwitchType === 'region')
|
||
"
|
||
type="danger"
|
||
class="selection-area-btn"
|
||
@click="clickDrawSelectionArea"
|
||
>确定</el-button
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="right-tool-list" v-if="state.isShowToolbar">
|
||
<div
|
||
v-for="item in state.rightToolList"
|
||
:key="item.switchType"
|
||
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>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="map-box" :style="{ cursor: state.cursorStyle }">
|
||
<div
|
||
class="map-box-inner"
|
||
@mousedown.stop="startDrawSelection"
|
||
@mousemove.stop="updateDrawSelection"
|
||
@mouseup.stop="endDrawSelection"
|
||
>
|
||
<img
|
||
:src="imgBgObj.imgUrl"
|
||
:style="{
|
||
width: Number(imgBgObj.width) * state.imageChangeMultiple + 'px',
|
||
height: Number(imgBgObj.height) * state.imageChangeMultiple + 'px'
|
||
}"
|
||
id="mapBg"
|
||
/>
|
||
<div
|
||
ref="mapBackgroundRef"
|
||
class="map-box-inner-dot"
|
||
@click="mapClick"
|
||
:class="state.isShowGrid ? 'grid-show' : ''"
|
||
:style="{
|
||
width: Number(imgBgObj.width) * state.imageChangeMultiple + 'px',
|
||
height: Number(imgBgObj.height) * state.imageChangeMultiple + 'px'
|
||
}"
|
||
v-if="interfaceRefreshed"
|
||
>
|
||
<VueDragResizeRotate
|
||
v-for="(item, index) in allHistoryList[currentIndex]"
|
||
:key="item.locationX"
|
||
:parent="true"
|
||
:x="Number(item.locationX) * state.imageChangeMultiple"
|
||
:y="Number(item.locationY) * state.imageChangeMultiple"
|
||
:w="Number(item.locationWide) * state.imageChangeMultiple"
|
||
:h="Number(item.locationDeep) * state.imageChangeMultiple"
|
||
:r="item.angle"
|
||
@rotatestop="(degree) => rotateEnd(degree, item, index)"
|
||
@dragstop="(x, y) => dragEnd(x, y, item, index)"
|
||
@resizestop="(x, y, width, height) => resizeEnd(x, y, width, height, item, index)"
|
||
@activated="() => activatedHandle(item, index)"
|
||
@deactivated="deactivatedHandle"
|
||
:draggable="item.draggable"
|
||
:resizable="item.resizable"
|
||
:rotatable="item.rotatable"
|
||
:lock-aspect-ratio="item.lockAspectRatio"
|
||
style="border: none"
|
||
>
|
||
<!-- 1 路径点 -->
|
||
<div
|
||
v-if="item.type === 1 && item.layerSelectionShow"
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: ' 1px dashed #000',
|
||
borderRadius: '50%',
|
||
backgroundColor: '#000'
|
||
}"
|
||
>
|
||
</div>
|
||
<!-- 2 库位点 -->
|
||
<img
|
||
v-if="item.type === 2 && item.layerSelectionShow"
|
||
src="https://api.znkjfw.com/admin-api/infra/file/4/get/库位库存_png_179_1739326653035.png"
|
||
alt=""
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
/>
|
||
<!-- 3 设备点 -->
|
||
<img
|
||
v-if="item.type === 3 && item.layerSelectionShow"
|
||
src="https://api.znkjfw.com/admin-api/infra/file/4/get/设备点_png_179_1739327151877.png"
|
||
alt=""
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
/>
|
||
<!-- 4 停车点 -->
|
||
<img
|
||
v-if="item.type === 4 && item.layerSelectionShow"
|
||
src="https://api.znkjfw.com/admin-api/infra/file/4/get/停车场-01_png_179_1739326933020.png"
|
||
alt=""
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
/>
|
||
<!-- 5 区域变更点 -->
|
||
<img
|
||
v-if="item.type === 5 && item.layerSelectionShow"
|
||
src="https://api.znkjfw.com/admin-api/infra/file/4/get/区域_png_179_1739327151876.png"
|
||
alt=""
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
/>
|
||
<!-- 6 等待点 -->
|
||
<img
|
||
v-if="item.type === 6 && item.layerSelectionShow"
|
||
src="https://api.znkjfw.com/admin-api/infra/file/4/get/等待点_png_179_1739326991439.png"
|
||
alt=""
|
||
:style="{
|
||
width: Number(item.locationWide) * state.imageChangeMultiple + 'px',
|
||
height: Number(item.locationDeep) * state.imageChangeMultiple + 'px',
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
/>
|
||
<div
|
||
v-if="item.type === 7 && item.layerSelectionShow"
|
||
:style="{
|
||
color: item.fontColor,
|
||
fontSize: item.fontSize + 'px',
|
||
fontFamily: item.fontFamily,
|
||
border: currentItemIndex === index ? '1px dashed #000' : 'none'
|
||
}"
|
||
>
|
||
{{ item.text }}
|
||
</div>
|
||
</VueDragResizeRotate>
|
||
</div>
|
||
|
||
<!-- 框选区域 -->
|
||
<div
|
||
v-for="(box, index) in state.allDrawSelectionAreaBox"
|
||
:key="index"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${box.x}px`,
|
||
top: `${box.y}px`,
|
||
width: `${box.width}px`,
|
||
height: `${box.height}px`,
|
||
border: '2px dashed #007bff',
|
||
backgroundColor: 'rgba(0, 123, 255, 0.1)',
|
||
zIndex: 999
|
||
}"
|
||
></div>
|
||
<!-- 当前框选区域 -->
|
||
<div
|
||
v-if="state.drawSelectionAreaShow"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${state.drawSelectionAreaBox.x}px`,
|
||
top: `${state.drawSelectionAreaBox.y}px`,
|
||
width: `${state.drawSelectionAreaBox.width}px`,
|
||
height: `${state.drawSelectionAreaBox.height}px`,
|
||
border: '2px dashed #007bff',
|
||
backgroundColor: 'rgba(0, 123, 255, 0.1)',
|
||
zIndex: 9999
|
||
}"
|
||
></div>
|
||
|
||
<!-- 测距 绘制点和连线 -->
|
||
<template v-if="state.measureDistancesPoints.length > 0">
|
||
<div
|
||
v-for="(point, index) in state.measureDistancesPoints"
|
||
:key="index"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${point.x}px`,
|
||
top: `${point.y}px`,
|
||
width: '10px',
|
||
height: '10px',
|
||
backgroundColor: '#00329F',
|
||
borderRadius: '50%'
|
||
}"
|
||
></div>
|
||
<div
|
||
v-if="state.measureDistancesPoints.length === 2"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${state.measureDistancesPoints[0].x + 5}px`,
|
||
top: `${state.measureDistancesPoints[0].y + 5}px`,
|
||
width: `${computedLineWidth}px`,
|
||
height: '2px',
|
||
backgroundColor: '#00329F',
|
||
transform: `rotate(${computedLineAngle}deg)`,
|
||
transformOrigin: '0 0',
|
||
textAlign: 'center'
|
||
}"
|
||
>
|
||
距离:{{ state.measureDistancesNum.toFixed(2) }}</div
|
||
>
|
||
</template>
|
||
|
||
<!-- 文字输入区域 -->
|
||
<input
|
||
v-if="state.showInputBox"
|
||
ref="inputBoxRef"
|
||
v-model="state.inputBoxValue"
|
||
@keyup.enter="handleInputEnd"
|
||
@blur="handleInputEnd"
|
||
:style="{
|
||
fontSize: state.inputBoxStyle.fontSize + 'px',
|
||
fontFamily: state.inputBoxStyle.fontFamily,
|
||
color: state.inputBoxStyle.fontColor,
|
||
left: state.inputBoxStyle.locationX + 'px',
|
||
top: state.inputBoxStyle.locationY + 'px'
|
||
}"
|
||
:maxlength="30"
|
||
class="input-box-class"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<!-- 节点编辑 -->
|
||
<editNodeProperties
|
||
ref="editNodePropertiesRef"
|
||
:positionMapId="imgBgObj.positionMapId"
|
||
@submitNodeSuccess="submitNodeSuccess"
|
||
/>
|
||
<!-- 文字输入弹窗 -->
|
||
<textFormToolDialog
|
||
ref="textFormToolDialogRef"
|
||
v-if="state.textFormToolShow"
|
||
:inputBoxStyle="inputBoxStyle"
|
||
@textFormSuccess="textFormSuccess"
|
||
/>
|
||
<!-- 图层选择 -->
|
||
<layerSelectionToolDialog
|
||
v-if="state.isShowLayer"
|
||
ref="layerSelectionToolDialogRef"
|
||
@layerSelectionSuccess="layerSelectionSuccess"
|
||
/>
|
||
<!-- 设备弹窗选择 -->
|
||
<equipmentToolDialog ref="equipmentToolDialogRef" :positionMapId="imgBgObj.positionMapId" />
|
||
<!-- 区域选择 -->
|
||
<itemAreaSettingDialog ref="itemAreaSettingDialogRef" :positionMapId="imgBgObj.positionMapId" />
|
||
<!-- 线库设置 -->
|
||
<lineLibrarySettingDialog
|
||
ref="lineLibrarySettingDialogRef"
|
||
:positionMapId="imgBgObj.positionMapId"
|
||
/>
|
||
</template>
|
||
|
||
<script setup>
|
||
import JSONBigInt from 'json-bigint'
|
||
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
|
||
import editNodeProperties from '../realTimeMap/components-tool/editNodeProperties.vue'
|
||
import textFormToolDialog from '../realTimeMap/components-tool/textFormToolDialog.vue'
|
||
import equipmentToolDialog from '../realTimeMap/components-tool/equipmentToolDialog.vue'
|
||
import itemAreaSettingDialog from '../realTimeMap/components-tool/itemAreaSettingDialog.vue'
|
||
import lineLibrarySettingDialog from '../realTimeMap/components-tool/lineLibrarySettingDialog.vue'
|
||
import layerSelectionToolDialog from '../realTimeMap/components-tool/layerSelectionToolDialog.vue'
|
||
|
||
import * as MapApi from '@/api/map/map'
|
||
import cursorCollection from '../realTimeMap/cursorCollection'
|
||
|
||
defineOptions({ name: 'editMapPageRealTimeMap' })
|
||
|
||
const lineLibrarySettingDialogRef = ref() //线库设置
|
||
const itemAreaSettingDialogRef = ref() //物料区域设置
|
||
const equipmentToolDialogRef = ref() //设备弹窗
|
||
const textFormToolDialogRef = ref() //文字输入弹窗
|
||
const mapBackgroundRef = ref()
|
||
const inputBoxRef = ref() //文字输入框
|
||
|
||
const message = useMessage() // 消息弹窗
|
||
const formLoading = ref(false)
|
||
|
||
const allHistoryList = ref([]) //全部的历史记录
|
||
const currentIndex = ref(0) //用于记录是哪条历史记录的
|
||
const currentItemIndex = ref(-1) //用于记录是在编辑那个具体的节点、图标等
|
||
const allMapPointInfo = ref([]) //所有的图标的列表
|
||
|
||
// 缩放停止
|
||
const interfaceRefreshed = ref(true)
|
||
const resizeEnd = (x, y, w, h, item, index) => {
|
||
interfaceRefreshed.value = false
|
||
console.log('缩放', w, h)
|
||
nextTick(() => {
|
||
allMapPointInfo.value[index].locationX = x
|
||
allMapPointInfo.value[index].locationY = y
|
||
allMapPointInfo.value[index].locationWide = w
|
||
allMapPointInfo.value[index].locationDeep = h
|
||
addEditHistory()
|
||
})
|
||
}
|
||
// 拖拽停止
|
||
const dragEnd = (x, y, item, index) => {
|
||
console.log('拖拽')
|
||
if (x === item.locationX && y === item.locationY) return
|
||
allMapPointInfo.value[index].locationX = x
|
||
allMapPointInfo.value[index].locationY = y
|
||
addEditHistory()
|
||
}
|
||
// 旋转
|
||
const rotateEnd = (angle, item, index) => {
|
||
console.log('旋转')
|
||
allMapPointInfo.value[index].angle = angle
|
||
addEditHistory()
|
||
}
|
||
|
||
//选中
|
||
const editNodePropertiesRef = ref()
|
||
const activatedHandle = (item, index) => {
|
||
currentItemIndex.value = index
|
||
|
||
//节点编辑
|
||
if (toolbarSwitchType.value === 'editNode' && item.type !== 7) {
|
||
editNodePropertiesRef.value.open(JSON.parse(JSON.stringify(item)))
|
||
}
|
||
}
|
||
//非选中
|
||
const deactivatedHandle = () => {
|
||
console.log('取消选中')
|
||
}
|
||
|
||
//添加历史记录
|
||
const addEditHistory = () => {
|
||
//要判断是不是在最新的记录上修改 如果不是 要把currentIndex之后的记录都删掉 保持当前修改是最新的
|
||
if (currentIndex.value !== allHistoryList.value.length - 1) {
|
||
allHistoryList.value = allHistoryList.value.splice(0, currentIndex.value)
|
||
currentIndex.value = allHistoryList.value.length
|
||
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
|
||
} else {
|
||
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
|
||
currentIndex.value++
|
||
}
|
||
interfaceRefreshed.value = true
|
||
console.log(allHistoryList.value, 'allHistoryList')
|
||
}
|
||
|
||
//上一步
|
||
const backPreviousStep = () => {
|
||
if (currentIndex.value > 0) {
|
||
currentIndex.value--
|
||
allMapPointInfo.value = allHistoryList.value[currentIndex.value]
|
||
console.log('撤销', allHistoryList.value[currentIndex.value])
|
||
} else {
|
||
message.warning('没了老铁')
|
||
}
|
||
}
|
||
//下一步
|
||
const backNextStep = () => {
|
||
if (currentIndex.value < allHistoryList.value.length - 1) {
|
||
currentIndex.value++
|
||
allMapPointInfo.value = allHistoryList.value[currentIndex.value]
|
||
console.log('重做', allHistoryList.value[currentIndex.value])
|
||
} else {
|
||
message.warning('没了老铁')
|
||
}
|
||
}
|
||
|
||
//地图点击
|
||
const mapClick = (e) => {
|
||
//节点
|
||
if (toolbarSwitchType.value === 'drawNodes') {
|
||
//绘制节点
|
||
allMapPointInfo.value.push({
|
||
positionMapId: imgBgObj.positionMapId, //地图的id
|
||
layerSelectionShow: true,
|
||
locationX: e.offsetX,
|
||
locationY: e.offsetY,
|
||
locationDeep: 16,
|
||
locationWide: 16,
|
||
angle: 0,
|
||
draggable: false,
|
||
resizable: false,
|
||
rotatable: false,
|
||
lockAspectRatio: false, //横纵比
|
||
img: '',
|
||
type: 1, //默认类型1 路径节点
|
||
dataList: [], //存库位的
|
||
dataObj: {} //存 设备点 停车点 文字
|
||
})
|
||
currentIndex.value++
|
||
allHistoryList.value.push(JSON.parse(JSON.stringify(allMapPointInfo.value)))
|
||
}
|
||
//文字输入
|
||
if (toolbarSwitchType.value === 'text') {
|
||
state.showInputBox = true
|
||
state.inputBoxStyle.locationX = e.offsetX
|
||
state.inputBoxStyle.locationY = e.offsetY
|
||
|
||
// 聚焦输入框
|
||
setTimeout(() => {
|
||
inputBoxRef.value.focus()
|
||
}, 0)
|
||
}
|
||
//测距
|
||
if (toolbarSwitchType.value === 'ranging') {
|
||
measureDistancesClick(e)
|
||
}
|
||
}
|
||
//输入文字样式改变
|
||
const textFormSuccess = (form) => {
|
||
state.inputBoxStyle = {
|
||
fontSize: `${form.fontSize}`,
|
||
fontFamily: `${form.fontFamily}`,
|
||
fontColor: `${form.fontColor}`
|
||
}
|
||
}
|
||
//输入结束
|
||
const handleInputEnd = () => {
|
||
if (state.inputBoxValue) {
|
||
state.showInputBox = false
|
||
allMapPointInfo.value.push({
|
||
type: 7, //类型 7文字
|
||
positionMapId: imgBgObj.positionMapId, //地图的id
|
||
locationX: state.inputBoxStyle.locationX, //x
|
||
locationY: state.inputBoxStyle.locationY, //y
|
||
locationDeep: '', //h
|
||
locationWide: '', //w
|
||
angle: 0, //旋转角度
|
||
draggable: true, //是否可以拖动
|
||
resizable: false, //是否可以调整大小
|
||
rotatable: false, //是否可以旋转
|
||
lockAspectRatio: true, //是否锁定比例
|
||
img: '', //图片
|
||
text: state.inputBoxValue, //文字内容
|
||
fontColor: state.inputBoxStyle.fontColor, //文字颜色
|
||
fontFamily: state.inputBoxStyle.fontFamily, //字体类型
|
||
fontSize: state.inputBoxStyle.fontSize,
|
||
dataObj: {}, //存 设备点 停车点 文字
|
||
layerSelectionShow: true
|
||
})
|
||
addEditHistory()
|
||
state.inputBoxValue = ''
|
||
}
|
||
}
|
||
//编辑节点成功
|
||
const submitNodeSuccess = (item) => {
|
||
allMapPointInfo.value[currentItemIndex.value] = item
|
||
allHistoryList.value[currentIndex.value][currentItemIndex.value] = item
|
||
}
|
||
|
||
//工具栏点击
|
||
const toolbarSwitchType = ref('')
|
||
const state = reactive({
|
||
topToolList: [
|
||
{
|
||
switchType: 'open',
|
||
name: '打开',
|
||
icon: 'ep:folder-add',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'save',
|
||
name: '保存',
|
||
icon: 'ep:folder-checked',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'saveAs',
|
||
name: '另存为',
|
||
icon: 'ep:folder-opened',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'choose',
|
||
name: '选择',
|
||
icon: 'ep:position',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'move',
|
||
name: '移动',
|
||
icon: 'ep:rank',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'revolve',
|
||
name: '旋转',
|
||
icon: 'ep:refresh-right',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'copy',
|
||
name: '复制',
|
||
icon: 'ep:document',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'paste',
|
||
name: '粘贴',
|
||
icon: 'ep:copy-document',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'delete',
|
||
name: '删除',
|
||
icon: 'ep:delete',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'tools',
|
||
name: '工具',
|
||
icon: 'ep:briefcase',
|
||
isActive: true
|
||
},
|
||
{
|
||
switchType: 'lineLibrary',
|
||
name: '线库',
|
||
icon: 'ep:message-box',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'region',
|
||
name: '区域',
|
||
icon: 'ep:full-screen',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'text',
|
||
name: '文字',
|
||
icon: 'ep:edit-pen',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'equipment',
|
||
name: '设备',
|
||
icon: 'ep:video-camera-filled',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'ranging',
|
||
name: '测距',
|
||
icon: 'ep:folder-add',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'layer',
|
||
name: '图层',
|
||
icon: 'ep:copy-document',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'marker',
|
||
name: '标记',
|
||
icon: 'ep:map-location',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'grid',
|
||
name: '网格',
|
||
icon: 'ep:grid',
|
||
isActive: true
|
||
},
|
||
{
|
||
switchType: 'larger',
|
||
name: '放大',
|
||
icon: 'ep:zoom-in',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'smaller',
|
||
name: '缩小',
|
||
icon: 'ep:zoom-out',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'withdraw',
|
||
name: '撤回',
|
||
icon: 'ep:top-left',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'next',
|
||
name: '重做',
|
||
icon: 'ep:top-right',
|
||
isActive: false
|
||
}
|
||
],
|
||
rightToolList: [
|
||
{
|
||
switchType: 'drawNodes',
|
||
name: '绘制节点',
|
||
icon: 'ep:circle-plus-filled',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'editNode',
|
||
name: '编辑节点',
|
||
icon: 'ep:circle-plus-filled',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'drawRoute',
|
||
name: '绘制路线',
|
||
icon: 'ep:semi-select',
|
||
isActive: false
|
||
},
|
||
{
|
||
switchType: 'editRoute',
|
||
name: '编辑路线',
|
||
icon: 'ep:semi-select',
|
||
isActive: false
|
||
}
|
||
],
|
||
isShowToolbar: true, //工具栏展示隐藏
|
||
isShowGrid: true, //网格展示隐藏
|
||
moveForm: {
|
||
locationX: '',
|
||
locationY: ''
|
||
}, //移动的表单
|
||
rotationForm: {
|
||
angle: ''
|
||
}, //旋转的表单
|
||
copyMapItem: '', //复制的值
|
||
cursorStyle: 'auto',
|
||
drawSelectionAreaShow: false, //绘制框选区域
|
||
allDrawSelectionAreaBox: [], // 所有框选区域
|
||
drawSelectionAreaBox: { x: 0, y: 0, width: 0, height: 0 }, //绘制区域的位置,长宽
|
||
drawSelectionStartPoint: { x: 0, y: 0 }, //开始绘制的点位
|
||
drawSelectionPointList: [], //绘制选中的list
|
||
textFormToolShow: false, //文字表单显示隐藏
|
||
showInputBox: false, //输入框显示隐藏
|
||
inputBoxStyle: {
|
||
fontFamily: 'SimSun',
|
||
fontSize: '14',
|
||
fontColor: '#000000',
|
||
locationX: 0,
|
||
locationY: 0
|
||
}, //输入框的样式
|
||
inputBoxValue: '', //输入的值
|
||
isShowLayer: false, //图层显示
|
||
measureDistancesPoints: [], // 存储点击的点位
|
||
measureDistancesNum: 0, // 存储两点之间的距离
|
||
imageChangeMultiple: 1 //图片放大缩小的倍数
|
||
})
|
||
const toolbarClick = (item) => {
|
||
let type = item.switchType
|
||
if (
|
||
currentItemIndex.value === -1 &&
|
||
(type === 'move' || type === 'revolve' || type === 'copy' || type === 'delete')
|
||
) {
|
||
message.warning('请先选择要操作的对象')
|
||
return
|
||
}
|
||
//粘贴
|
||
if (type === 'paste' && !state.copyMapItem) {
|
||
message.warning('请先复制对象')
|
||
return
|
||
}
|
||
|
||
if (
|
||
(type === 'tools' || type === 'text' || type === 'layer' || type === 'grid') &&
|
||
toolbarSwitchType.value === type
|
||
) {
|
||
toolbarSwitchType.value = ''
|
||
} else {
|
||
toolbarSwitchType.value = type
|
||
}
|
||
|
||
if (toolbarSwitchType.value !== 'text') {
|
||
state.cursorStyle = `auto`
|
||
state.textFormToolShow = false
|
||
state.showInputBox = false
|
||
state.inputBoxValue = ''
|
||
}
|
||
|
||
//工具切换 不适用框选的 要把框选的信息都删掉
|
||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') {
|
||
state.drawSelectionAreaShow = false
|
||
state.allDrawSelectionAreaBox = []
|
||
state.drawSelectionPointList = []
|
||
}
|
||
//非测距
|
||
if (toolbarSwitchType.value !== 'ranging') {
|
||
state.measureDistancesPoints = [] // 清空存储点击的点位
|
||
state.measureDistancesNum = 0 // 清空存储两点之间的距离
|
||
}
|
||
|
||
switch (type) {
|
||
case 'open':
|
||
// 打开
|
||
break
|
||
case 'save':
|
||
//保存
|
||
saveMap()
|
||
break
|
||
case 'saveAs':
|
||
//另存为 存为json文件 无法直接访问用户的文件系统 不能选择存在那个文件夹里面
|
||
const jsonString = JSON.stringify(allHistoryList.value[currentIndex.value], null, 2)
|
||
const blob = new Blob([jsonString], { type: 'application/json' })
|
||
const url = URL.createObjectURL(blob)
|
||
|
||
const a = document.createElement('a')
|
||
a.href = url
|
||
a.download = 'mapJson.json'
|
||
document.body.appendChild(a)
|
||
a.click()
|
||
document.body.removeChild(a)
|
||
URL.revokeObjectURL(url)
|
||
|
||
message.success('下载成功')
|
||
break
|
||
case 'choose':
|
||
//选择
|
||
break
|
||
case 'move':
|
||
//移动
|
||
break
|
||
case 'revolve':
|
||
break
|
||
case 'copy':
|
||
//复制
|
||
let copyMapItem = allHistoryList.value[currentIndex.value][currentItemIndex.value]
|
||
state.copyMapItem = {
|
||
positionMapId: copyMapItem.positionMapId,
|
||
locationX: copyMapItem.locationX,
|
||
locationY: copyMapItem.locationY,
|
||
type: copyMapItem.type,
|
||
dataJson: copyMapItem.dataJson || '',
|
||
dataObj: copyMapItem.dataObj || {},
|
||
dataList: copyMapItem.dataList || [],
|
||
locationDeep: copyMapItem.locationDeep,
|
||
locationWide: copyMapItem.locationWide,
|
||
draggable: copyMapItem.draggable,
|
||
resizable: copyMapItem.resizable,
|
||
rotatable: copyMapItem.rotatable,
|
||
lockAspectRatio: copyMapItem.lockAspectRatio
|
||
}
|
||
message.success('复制成功')
|
||
break
|
||
case 'paste':
|
||
//粘贴
|
||
let copyObj = JSON.parse(JSON.stringify(state.copyMapItem))
|
||
copyObj.locationX = Number(copyObj.locationX) + 50
|
||
copyObj.locationY = Number(copyObj.locationY) + 50
|
||
allMapPointInfo.value.push(copyObj)
|
||
addEditHistory()
|
||
break
|
||
case 'delete':
|
||
//删除
|
||
allMapPointInfo.value.splice(currentItemIndex.value, 1)
|
||
addEditHistory()
|
||
break
|
||
case 'tools':
|
||
//工具
|
||
if (toolbarSwitchType.value === 'tools') {
|
||
state.isShowToolbar = true
|
||
item.isActive = true
|
||
} else {
|
||
state.isShowToolbar = false
|
||
item.isActive = false
|
||
}
|
||
break
|
||
case 'lineLibrary':
|
||
// 线库
|
||
break
|
||
case 'region':
|
||
// 区域
|
||
break
|
||
case 'text':
|
||
//文字
|
||
if (toolbarSwitchType.value === 'text') {
|
||
state.textFormToolShow = true
|
||
state.cursorStyle = `url('${cursorCollection.input}'),auto`
|
||
} else {
|
||
state.cursorStyle = `auto`
|
||
state.textFormToolShow = false
|
||
state.showInputBox = false
|
||
state.inputBoxValue = ''
|
||
}
|
||
break
|
||
case 'ranging':
|
||
// 测距
|
||
break
|
||
case 'layer':
|
||
//图层
|
||
if (toolbarSwitchType.value === 'layer') {
|
||
state.isShowLayer = true
|
||
item.isActive = true
|
||
} else {
|
||
state.isShowLayer = false
|
||
item.isActive = false
|
||
}
|
||
break
|
||
case 'marker':
|
||
// 标记
|
||
break
|
||
case 'grid':
|
||
//网格
|
||
if (toolbarSwitchType.value === 'grid') {
|
||
state.isShowGrid = true
|
||
item.isActive = true
|
||
} else {
|
||
state.isShowGrid = false
|
||
item.isActive = false
|
||
}
|
||
break
|
||
case 'larger':
|
||
//放大
|
||
if (imgBgObj.width < 10000) {
|
||
state.imageChangeMultiple *= 1.2
|
||
} else {
|
||
message.warning('不能在放大了')
|
||
}
|
||
break
|
||
case 'smaller':
|
||
//缩小
|
||
if (imgBgObj.width > 500) {
|
||
state.imageChangeMultiple *= 0.8
|
||
} else {
|
||
message.warning('不能在缩小了')
|
||
}
|
||
break
|
||
case 'withdraw':
|
||
//上一步
|
||
backPreviousStep()
|
||
break
|
||
case 'next':
|
||
//下一步
|
||
backNextStep()
|
||
break
|
||
case 'drawNodes':
|
||
//绘制节点
|
||
break
|
||
case 'editNode':
|
||
// 编辑节点
|
||
break
|
||
case 'drawRoute':
|
||
//绘制路线
|
||
break
|
||
case 'editRoute':
|
||
// 编辑路线
|
||
break
|
||
case 'equipment':
|
||
// 设备
|
||
equipmentToolDialogRef.value.open()
|
||
break
|
||
}
|
||
}
|
||
|
||
//移动工具表单提交
|
||
const moveFormSubmit = () => {
|
||
allHistoryList.value[currentIndex.value][currentItemIndex.value].locationX =
|
||
state.moveForm.locationX
|
||
allHistoryList.value[currentIndex.value][currentItemIndex.value].locationY =
|
||
state.moveForm.locationY
|
||
}
|
||
//旋转工具表单提交
|
||
const rotationFormSubmit = () => {
|
||
allHistoryList.value[currentIndex.value][currentItemIndex.value].angle = state.rotationForm.angle
|
||
}
|
||
|
||
//开始框选绘制
|
||
const startDrawSelection = (event) => {
|
||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||
|
||
const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()
|
||
|
||
const x = Number(event.clientX) - backgroundRect.left
|
||
const y = event.clientY - backgroundRect.top
|
||
|
||
// 确保点击在背景区域内
|
||
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) => {
|
||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||
if (state.drawSelectionAreaShow) {
|
||
const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()
|
||
const x = event.clientX - backgroundRect.left
|
||
const y = event.clientY - backgroundRect.top
|
||
|
||
state.drawSelectionAreaBox.width = Number(x) - Number(state.drawSelectionStartPoint.x)
|
||
state.drawSelectionAreaBox.height = Number(y) - Number(state.drawSelectionStartPoint.y)
|
||
}
|
||
// 阻止默认行为(避免选中图片或文本)
|
||
event.preventDefault()
|
||
}
|
||
//结束框选绘制
|
||
const endDrawSelection = () => {
|
||
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
|
||
state.drawSelectionAreaShow = false
|
||
state.allDrawSelectionAreaBox.push({ ...state.drawSelectionAreaBox })
|
||
state.drawSelectionAreaBox = { x: 0, y: 0, width: 0, height: 0 }
|
||
}
|
||
//点击区域
|
||
const clickDrawSelectionArea = () => {
|
||
let points = allHistoryList.value[currentIndex.value]
|
||
|
||
state.drawSelectionPointList = []
|
||
state.allDrawSelectionAreaBox.forEach((box) => {
|
||
points.forEach((point) => {
|
||
if (
|
||
point.locationX >= box.x &&
|
||
point.locationX <= box.x + box.width &&
|
||
point.locationY >= box.y &&
|
||
point.locationY <= box.y + box.height
|
||
) {
|
||
state.drawSelectionPointList.push(point)
|
||
}
|
||
})
|
||
})
|
||
|
||
console.log(state.drawSelectionPointList, '选中的')
|
||
|
||
// 清空框选区域
|
||
state.allDrawSelectionAreaBox = []
|
||
//只要库位的
|
||
let binLocation = state.drawSelectionPointList.filter((item) => item.type === 2)
|
||
|
||
if (toolbarSwitchType.value === 'lineLibrary') {
|
||
//线库
|
||
if (binLocation.length < 2) {
|
||
message.warning('至少选择两个库位')
|
||
return
|
||
}
|
||
if (!isStraightLine(binLocation)) {
|
||
message.warning('您选择的库位不在一条直线上')
|
||
return
|
||
}
|
||
lineLibrarySettingDialogRef.value.open(binLocation)
|
||
}
|
||
if (toolbarSwitchType.value === 'region') {
|
||
//区域
|
||
if (binLocation.length < 1) {
|
||
message.warning('至少选择两个库位')
|
||
} else {
|
||
itemAreaSettingDialogRef.value.open(binLocation)
|
||
}
|
||
}
|
||
}
|
||
//计算是不是在同一条直线的
|
||
const isStraightLine = (binLocation) => {
|
||
if (binLocation.length <= 2) {
|
||
return true // 两个点一定在一条直线上
|
||
}
|
||
|
||
const firstPoint = binLocation[0]
|
||
const secondPoint = binLocation[1]
|
||
|
||
// 检查是否垂直直线(所有 x 相同)
|
||
const isVertical = binLocation.every(
|
||
(point) => Number(point.locationX) === Number(firstPoint.locationX)
|
||
)
|
||
if (isVertical) {
|
||
return true
|
||
}
|
||
|
||
// 检查是否水平直线(所有 y 相同)
|
||
const isHorizontal = binLocation.every(
|
||
(point) => Number(point.locationY) === Number(firstPoint.locationY)
|
||
)
|
||
if (isHorizontal) {
|
||
return true
|
||
}
|
||
|
||
// 计算斜率
|
||
const slope =
|
||
Number(secondPoint.locationY) -
|
||
Number(firstPoint.locationY) / (Number(secondPoint.locationX) - Number(firstPoint.locationX))
|
||
|
||
// 检查所有点是否在同一条斜线上
|
||
return binLocation.every((point) => {
|
||
const currentSlope =
|
||
(Number(point.locationY) - Number(firstPoint.locationY)) /
|
||
(Number(point.locationX) - Number(firstPoint.locationX))
|
||
return Math.abs(currentSlope - slope) < Number.EPSILON // 处理浮点数精度问题
|
||
})
|
||
}
|
||
|
||
//测距相关
|
||
// 计算两点之间的距离
|
||
const calculateDistance = (point1, point2) => {
|
||
const dx = point2.x - point1.x
|
||
const dy = point2.y - point1.y
|
||
return Math.sqrt(dx * dx + dy * dy)
|
||
}
|
||
|
||
// 计算连线的角度
|
||
const computedLineAngle = computed(() => {
|
||
if (state.measureDistancesPoints.length === 2) {
|
||
const dx = state.measureDistancesPoints[1].x - state.measureDistancesPoints[0].x
|
||
const dy = state.measureDistancesPoints[1].y - state.measureDistancesPoints[0].y
|
||
return Math.atan2(dy, dx) * (180 / Math.PI)
|
||
}
|
||
return 0
|
||
})
|
||
|
||
// 计算连线的长度
|
||
const computedLineWidth = computed(() => {
|
||
if (state.measureDistancesPoints.length === 2) {
|
||
return calculateDistance(state.measureDistancesPoints[0], state.measureDistancesPoints[1])
|
||
}
|
||
return 0
|
||
})
|
||
|
||
// 处理点击事件
|
||
const measureDistancesClick = (event) => {
|
||
// 获取点击点相对于整个页面的坐标
|
||
const x = event.clientX
|
||
const y = event.clientY
|
||
|
||
// 检查点击是否发生在背景区域内
|
||
const backgroundRect = mapBackgroundRef.value.getBoundingClientRect()
|
||
if (
|
||
x >= backgroundRect.left &&
|
||
x <= backgroundRect.right &&
|
||
y >= backgroundRect.top &&
|
||
y <= backgroundRect.bottom
|
||
) {
|
||
if (state.measureDistancesPoints.length === 2) {
|
||
// 如果已经有两个点,清空信息
|
||
state.measureDistancesPoints = []
|
||
state.measureDistancesNum = null
|
||
} else {
|
||
// 记录点击的点位(相对于背景区域的坐标)
|
||
const offsetX = x - backgroundRect.left
|
||
const offsetY = y - backgroundRect.top
|
||
state.measureDistancesPoints.push({ x: offsetX, y: offsetY })
|
||
if (state.measureDistancesPoints.length === 2) {
|
||
// 计算两点之间的距离
|
||
state.measureDistancesNum = calculateDistance(
|
||
state.measureDistancesPoints[0],
|
||
state.measureDistancesPoints[1]
|
||
)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//获取扫描图 地图背景相关的信息
|
||
const imgBgObj = reactive({
|
||
imgUrl: '',
|
||
positionMapId: '',
|
||
width: '',
|
||
height: '',
|
||
floor: '',
|
||
area: ''
|
||
})
|
||
//接收参数
|
||
const { query } = useRoute() // 查询参数
|
||
//获取地图点位
|
||
const getMapList = async () => {
|
||
if (query.mapId) {
|
||
imgBgObj.positionMapId = query.mapId
|
||
imgBgObj.floor = query.floor
|
||
imgBgObj.area = query.area
|
||
//调转换成png的接口
|
||
getMapData(imgBgObj)
|
||
}
|
||
}
|
||
//调转换成png的接口
|
||
const getMapData = async (mapInfo) => {
|
||
let data = await MapApi.getPositionMapdDwnloadPngBase64({
|
||
floor: mapInfo.floor,
|
||
area: mapInfo.area
|
||
})
|
||
imgBgObj.imgUrl = data
|
||
|
||
//获取一下图片的宽高
|
||
const img = new Image()
|
||
img.src = imgBgObj.imgUrl
|
||
//加载图片成功
|
||
img.onload = () => {
|
||
imgBgObj.width = img.naturalWidth
|
||
imgBgObj.height = img.naturalHeight
|
||
getAllNodeList()
|
||
}
|
||
//加载图片失败
|
||
img.onerror = () => {
|
||
console.error('图片加载失败')
|
||
}
|
||
}
|
||
//获取所有的点位 处理七种类型的
|
||
const getAllNodeList = async () => {
|
||
let list = await MapApi.getPositionMapItemList({
|
||
positionMapId: imgBgObj.positionMapId
|
||
})
|
||
list.forEach((item) => {
|
||
item.layerSelectionShow = true //用于图层
|
||
item.locationX = Number(item.locationX)
|
||
item.locationY = Number(item.locationY)
|
||
|
||
if (item.type === 1 || item.type === 5 || item.type === 6) {
|
||
item.dataObj = {}
|
||
item.dataList = []
|
||
item.locationDeep = 16
|
||
item.locationWide = 16
|
||
item.draggable = false
|
||
item.resizable = false
|
||
item.rotatable = false
|
||
item.lockAspectRatio = true
|
||
} else if (item.type === 2) {
|
||
//库位点
|
||
item.dataList = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
|
||
item.locationDeep = item.dataList[0].locationDeep
|
||
item.locationWide = item.dataList[0].locationWide
|
||
item.draggable = true
|
||
item.resizable = false
|
||
item.rotatable = false
|
||
item.lockAspectRatio = true
|
||
} else if (item.type === 3 || item.type === 4) {
|
||
item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
|
||
item.dataList = []
|
||
item.locationDeep = item.dataObj.locationDeep
|
||
item.locationWide = item.dataObj.locationWide
|
||
item.draggable = true
|
||
item.resizable = false
|
||
item.rotatable = false
|
||
item.lockAspectRatio = true
|
||
} else if (item.type === 7) {
|
||
item.dataObj = JSONBigInt({ storeAsString: true }).parse(item.dataJson)
|
||
item.text = item.dataObj.text
|
||
item.fontColor = item.dataObj.fontColor
|
||
item.fontFamily = item.dataObj.fontFamily
|
||
item.fontSize = item.dataObj.fontSize
|
||
item.angle = item.dataObj.angle
|
||
item.draggable = true
|
||
item.resizable = false
|
||
item.rotatable = true
|
||
item.lockAspectRatio = true
|
||
}
|
||
allMapPointInfo.value.push(item)
|
||
})
|
||
allHistoryList.value[0] = JSON.parse(JSON.stringify(allMapPointInfo.value))
|
||
}
|
||
|
||
//保存地图按钮
|
||
const saveMap = async () => {
|
||
//节点的保存
|
||
await saveNodeList()
|
||
//路线的保存
|
||
}
|
||
//节点的保存
|
||
const saveNodeList = async () => {
|
||
formLoading.value = true
|
||
let list = allHistoryList.value[currentIndex.value]
|
||
|
||
list.forEach((item) => {
|
||
if (item.type === 7) {
|
||
item.dataObj.positionMapId = imgBgObj.positionMapId
|
||
item.dataObj.text = item.text
|
||
item.dataObj.fontColor = item.fontColor
|
||
item.dataObj.fontType = item.fontType
|
||
item.dataObj.fontFamily = item.fontFamily
|
||
item.dataObj.rotatable = item.rotatable
|
||
item.dataObj.angle = item.angle
|
||
//dataJson数据
|
||
item.dataJson = JSON.stringify(item.dataObj)
|
||
}
|
||
})
|
||
|
||
try {
|
||
await MapApi.batchSaveOrEditOrDelMapItem(imgBgObj.positionMapId, list)
|
||
message.success('创建成功')
|
||
} finally {
|
||
formLoading.value = false
|
||
}
|
||
}
|
||
|
||
//筛选图层
|
||
const layerSelectionSuccess = (typeList) => {
|
||
allHistoryList.value[currentIndex.value].forEach((item) => {
|
||
// 如果 type 存在于第一个数组中,则将 layerSelectionShow 设置为 false
|
||
if (typeList.includes(item.type)) {
|
||
item.layerSelectionShow = false
|
||
} else {
|
||
item.layerSelectionShow = true
|
||
}
|
||
})
|
||
}
|
||
|
||
onMounted(() => {
|
||
getMapList()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.map-box {
|
||
width: 100%;
|
||
position: relative;
|
||
|
||
.map-box-inner {
|
||
position: relative;
|
||
width: 100%;
|
||
|
||
.map-box-inner-dot {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
}
|
||
|
||
.grid-show {
|
||
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
||
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
||
background-size:
|
||
10px 10px,
|
||
10px 10px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.top-tool {
|
||
.top-tool-list {
|
||
display: flex;
|
||
align-items: center;
|
||
text-align: center;
|
||
background-color: #fff;
|
||
margin-top: -15px;
|
||
margin-left: -20px;
|
||
margin-right: -20px;
|
||
padding: 0 12px;
|
||
margin-bottom: 20px;
|
||
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
|
||
height: 70px;
|
||
|
||
.top-tool-item {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.tool-item {
|
||
cursor: pointer;
|
||
width: 49px;
|
||
height: 70px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.name {
|
||
cursor: pointer;
|
||
font-family:
|
||
PingFangSC,
|
||
PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
color: #0d162a;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
.line {
|
||
margin: 0 12px;
|
||
width: 1px;
|
||
height: 47px;
|
||
border: 1px solid #cccccc;
|
||
}
|
||
}
|
||
}
|
||
|
||
.right-tool-list {
|
||
position: absolute;
|
||
right: 0;
|
||
top: 94px;
|
||
background-color: #fff;
|
||
z-index: 999;
|
||
text-align: center;
|
||
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
|
||
|
||
.tool-item {
|
||
cursor: pointer;
|
||
padding: 10px;
|
||
.name {
|
||
font-family:
|
||
PingFangSC,
|
||
PingFang SC;
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
color: #0d162a;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tool-active {
|
||
background: #ebf1ff;
|
||
border-bottom: 2px solid #1677ff;
|
||
}
|
||
|
||
.right-tool-active {
|
||
background: #ebf1ff;
|
||
}
|
||
}
|
||
|
||
.input-box-class {
|
||
position: absolute;
|
||
border: 1px solid #00329f;
|
||
padding: 4px;
|
||
outline: none;
|
||
}
|
||
|
||
.selection-area-btn {
|
||
width: 80px;
|
||
margin-left: 4px;
|
||
}
|
||
</style>
|