地图编辑

This commit is contained in:
yyy 2025-02-07 18:12:19 +08:00
parent 21ef0251a6
commit 9d0cc0b096
4 changed files with 458 additions and 179 deletions

View File

@ -80,7 +80,7 @@ watch(
layout === 'topLeft' || layout === 'top' || layout === 'cutMenu'
}
]"
style="font-size: 14px"
style="font-size: 13px"
>
{{ title }}
</div>

View File

@ -55,7 +55,7 @@ export const useRenderLayout = () => {
'w-[var(--left-menu-max-width)]': !appStore.getCollapse
}
]}
style="transition: all var(--transition-time-02);height:60px;display: flex;
style="transition: all var(--transition-time-02);height:59px;display: flex;
align-items: center;"
></Logo>
) : undefined}

View File

@ -3,7 +3,7 @@
--login-bg-color: #293146;
--left-menu-max-width: 220px;
--left-menu-max-width: 200px;
--left-menu-min-width: 64px;

View File

@ -1,109 +1,75 @@
<template>
<div>
<ContentWrap>
<div class="tool-list">
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 打开 </div>
<div class="top-tool-list">
<div v-for="item in state.topToolList" :key="item.id" class="top-tool-item">
<el-popover
placement="bottom"
:width="80"
trigger="click"
v-if="item.id === 5"
:disabled="currentItemIndex === -1"
>
<template #reference>
<div
class="tool-item"
:class="
toolbarTypeIndex === item.id
? '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="tool-item" @click="saveMap">
<Icon icon="ep:folder-checked" :size="24" />
<div class="name"> 保存 </div>
</template>
<el-form :model="state.moveForm">
<el-form-item label="X">
<el-input v-model="state.moveForm.x" 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>
<div class="tool-item">
<Icon icon="ep:folder-opened" :size="24" />
<div class="name"> 另存为 </div>
</el-form>
</el-popover>
<div
v-if="item.id !== 5"
class="tool-item"
:class="
toolbarTypeIndex === item.id ? '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.id === 3 || item.id === 10 || item.id === 19"></div>
</div>
</div>
<div class="right-tool-list">
<div
v-for="item in state.rightToolList"
:key="item.id"
class="tool-item"
:class="
toolbarTypeIndex === item.id ? '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"></div>
<div class="tool-item">
<Icon icon="ep:position" :size="24" />
<div class="name"> 选择 </div>
</div>
<div class="tool-item">
<Icon icon="ep:rank" :size="24" />
<div class="name"> 移动 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 旋转 </div>
</div>
<div class="tool-item">
<Icon icon="ep:document" :size="24" />
<div class="name"> 复制 </div>
</div>
<div class="tool-item">
<Icon icon="ep:copy-document" :size="24" />
<div class="name"> 粘贴 </div>
</div>
<div class="tool-item">
<Icon icon="ep:delete" :size="24" />
<div class="name"> 删除 </div>
</div>
<div class="line"></div>
<div class="tool-item">
<Icon icon="ep:briefcase" :size="24" />
<div class="name"> 工具 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 线库 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 区域 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 文字 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 设备 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 车辆 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 测距 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 图层 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 标记 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 网格 </div>
</div>
<div class="line"></div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 放大 </div>
</div>
<div class="tool-item">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 缩小 </div>
</div>
<div class="tool-item" @click="backPreviousStep">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 撤回 </div>
</div>
<div class="tool-item" @click="backNextStep">
<Icon icon="ep:folder-add" :size="24" />
<div class="name"> 重做 </div>
</div>
</div>
<!-- <el-button type="primary" @click="drawNodes" :disabled="formLoading"> 绘制节点 </el-button> -->
</ContentWrap>
<div class="map-box" ref="imgWrap" @mousewheel.prevent="rollImg" style="overflow: hidden">
<div class="map-box-inner" ref="image" @mousedown.prevent="moveImg">
<img :src="imgBgObj.imgUrl" class="map-box-img" id="mapBg" />
<div class="map-box-inner-dot" @click="mapClick">
<div class="map-box-inner-dot" @click="mapClick" :class="state.isShowGrid ? 'grid-show' : ''">
<VueDragResizeRotate
v-for="(item, index) in allHistoryList[currentIndex]"
:key="index"
@ -146,7 +112,6 @@
:positionMapId="imgBgObj.positionMapId"
@submitNodeSuccess="submitNodeSuccess"
/>
</div>
</template>
<script setup>
@ -161,7 +126,7 @@ const formLoading = ref(false)
const allHistoryList = ref([]) //
const currentIndex = ref(0) //
const currentItemIndex = ref(0) //
const currentItemIndex = ref(-1) //
const imgBgObj = reactive({
imgUrl: '',
positionMapId: ''
@ -229,9 +194,11 @@ const activatedHandle = (item, index) => {
console.log('选中', item)
currentItemIndex.value = index
if (item.labelType === 'node') {
if (toolbarTypeIndex.value === 25) {
editNodePropertiesRef.value.open(item)
}
}
}
//
const deactivatedHandle = () => {
console.log('取消选中')
@ -271,19 +238,10 @@ const backNextStep = () => {
message.warning('没了老铁')
}
}
//
const toolTypeIndex = ref(0)
const cursorType = ref('')
const drawNodes = () => {
if (toolTypeIndex.value === 1) {
toolTypeIndex.value = 0
} else {
toolTypeIndex.value = 1
}
}
//
const mapClick = (e) => {
if (toolTypeIndex.value === 1) {
if (toolbarTypeIndex.value === 24) {
//
imgList.value.push({
x: e.offsetX,
@ -297,7 +255,6 @@ const mapClick = (e) => {
img: '',
labelType: 'node'
})
console.log(imgList.value)
currentIndex.value++
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
}
@ -338,6 +295,273 @@ const submitNodeSuccess = (item) => {
allHistoryList.value[currentIndex.value][currentItemIndex.value] = item
}
//
const toolbarTypeIndex = ref(0)
const state = reactive({
topToolList: [
{
id: 1,
name: '打开',
icon: 'ep:folder-add',
isActive: false
},
{
id: 2,
name: '保存',
icon: 'ep:folder-checked',
isActive: false
},
{
id: 3,
name: '另存为',
icon: 'ep:folder-opened',
isActive: false
},
{
id: 4,
name: '选择',
icon: 'ep:position',
isActive: false
},
{
id: 5,
name: '移动',
icon: 'ep:rank',
isActive: false
},
{
id: 6,
name: '旋转',
icon: 'ep:folder-add',
isActive: false
},
{
id: 7,
name: '复制',
icon: 'ep:document',
isActive: false
},
{
id: 8,
name: '粘贴',
icon: 'ep:copy-document',
isActive: false
},
{
id: 9,
name: '删除',
icon: 'ep:delete',
isActive: false
},
{
id: 10,
name: '工具',
icon: 'ep:briefcase',
isActive: false
},
{
id: 11,
name: '线库',
icon: 'ep:folder-add',
isActive: false
},
{
id: 12,
name: '区域',
icon: 'ep:folder-add',
isActive: false
},
{
id: 13,
name: '文字',
icon: 'ep:folder-add',
isActive: false
},
{
id: 14,
name: '设备',
icon: 'ep:folder-add',
isActive: false
},
{
id: 15,
name: '车辆',
icon: 'ep:folder-add',
isActive: false
},
{
id: 16,
name: '测距',
icon: 'ep:folder-add',
isActive: false
},
{
id: 17,
name: '图层',
icon: 'ep:folder-add',
isActive: false
},
{
id: 18,
name: '标记',
icon: 'ep:folder-add',
isActive: false
},
{
id: 19,
name: '网格',
icon: 'ep:folder-add',
isActive: false
},
{
id: 20,
name: '放大',
icon: 'ep:zoom-in',
isActive: false
},
{
id: 21,
name: '缩小',
icon: 'ep:zoom-out',
isActive: false
},
{
id: 22,
name: '撤回',
icon: 'ep:top-left',
isActive: false
},
{
id: 23,
name: '重做',
icon: 'ep:top-right',
isActive: false
}
],
rightToolList: [
{
id: 24,
name: '绘制节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
id: 25,
name: '编辑节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
id: 26,
name: '绘制路线',
icon: 'ep:semi-select',
isActive: false
},
{
id: 27,
name: '编辑路线',
icon: 'ep:semi-select',
isActive: false
}
],
isShowGrid: false,
moveForm: {
x: '',
y: ''
}
})
const toolbarClick = (item) => {
let type = item.id
if (currentItemIndex.value === -1 && type === 5) {
message.warning('请先选择要操作的图标')
return
}
if (toolbarTypeIndex.value === type) {
toolbarTypeIndex.value = 0
} else {
toolbarTypeIndex.value = type
}
switch (type) {
case 1:
break
case 2:
saveMap()
break
case 3:
break
case 4:
break
case 5:
break
case 6:
break
case 7:
break
case 8:
break
case 9:
break
case 10:
break
case 11:
break
case 12:
break
case 13:
break
case 14:
break
case 15:
break
case 16:
break
case 17:
break
case 18:
break
case 19:
//
if (toolbarTypeIndex.value === 19) {
state.isShowGrid = true
item.isActive = true
} else {
state.isShowGrid = false
item.isActive = false
}
break
case 20:
break
case 21:
break
case 22:
//
backPreviousStep()
break
case 23:
//
backNextStep()
break
case 24:
drawNodes()
break
case 25:
break
case 26:
break
case 27:
break
default:
break
}
}
//
const moveFormSubmit = () => {
allHistoryList.value[currentIndex.value][currentItemIndex.value].x = state.moveForm.x
allHistoryList.value[currentIndex.value][currentItemIndex.value].y = state.moveForm.y
}
onMounted(() => {
imgList.value = [
{
@ -389,6 +613,9 @@ onMounted(() => {
left: 0;
top: 0;
bottom: 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:
@ -403,14 +630,31 @@ onMounted(() => {
height: 100%;
}
.tool-list {
.top-tool-list {
display: flex;
align-items: center;
text-align: center;
background-color: #fff;
margin-top: -20px;
margin-left: -20px;
margin-right: -20px;
padding: 0 14px;
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 {
width: 50px;
}
cursor: pointer;
width: 52px;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.name {
font-family:
@ -423,7 +667,7 @@ onMounted(() => {
text-align: center;
font-style: normal;
}
}
.line {
margin: 0 14px;
width: 1px;
@ -431,4 +675,39 @@ onMounted(() => {
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;
}
</style>