地图编辑

This commit is contained in:
yyy 2025-02-10 18:07:22 +08:00
parent ce81a142a7
commit 2f8d31b63c
15 changed files with 589 additions and 193 deletions

View File

@ -18,7 +18,7 @@
</el-select>
</ElDialog>
<div v-else class="custom-hover" @click.stop="showTopSearch = !showTopSearch">
<Icon icon="ep:search" />
<Icon icon="ep:search" color="var(--top-header-text-color)" />
<el-select
@click.stop
filterable

View File

@ -59,7 +59,7 @@ export default defineComponent({
<Backtop></Backtop>
{<Setting></Setting>}
{/* <Setting></Setting> */}
</section>
)
}

View File

@ -54,7 +54,13 @@ onMounted(() => {
<ElPopover :width="400" placement="bottom" trigger="click">
<template #reference>
<ElBadge :is-dot="unreadCount > 0" class="item">
<Icon :size="18" class="cursor-pointer" icon="ep:bell" @click="getList" />
<Icon
:size="18"
class="cursor-pointer"
icon="ep:bell"
@click="getList"
color="var(--top-header-text-color)"
/>
</ElBadge>
</template>
<ElTabs v-model="activeName">

View File

@ -297,6 +297,6 @@ $prefix-cls: #{$namespace}-setting;
.#{$prefix-cls} {
border-radius: 6px 0 0 6px;
z-index: 1200;/*修正没有z-index会被表格层覆盖,值不要超过4000*/
z-index: 1200; /*修正没有z-index会被表格层覆盖,值不要超过4000*/
}
</style>

View File

@ -1,6 +1,6 @@
<script lang="tsx">
import { defineComponent, computed } from 'vue'
import { Message } from '@/layout/components//Message'
import { Message } from '@/layout/components/Message'
import { Collapse } from '@/layout/components/Collapse'
import { UserInfo } from '@/layout/components/UserInfo'
import { Screenfull } from '@/layout/components/Screenfull'
@ -52,7 +52,7 @@ export default defineComponent({
'h-[var(--top-tool-height)] relative px-[var(--top-tool-p-x)] flex items-center justify-between',
'dark:bg-[var(--el-bg-color)]'
]}
style="height:60px"
style="height:61px"
>
{layout.value !== 'top' ? (
<div class="h-full flex items-center">

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:59px;display: flex;
style="transition: all var(--transition-time-02);height:60px;display: flex;
align-items: center;"
></Logo>
) : undefined}

View File

@ -72,7 +72,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
},
//地图
{
path: '/warehouse/map', // 商品中心
path: '/warehouse/map',
component: Layout,
name: 'warehouseMap',
meta: {

View File

@ -94,7 +94,7 @@ export const useAppStore = defineStore('app', {
// 头部字体颜色
topHeaderTextColor: '#ffffff',
// 头部悬停颜色
topHeaderHoverColor: '#f6f6f6',
topHeaderHoverColor: '#215bd8',
// 头部边框颜色
topToolBorderColor: '#E2E7F5'
}

View File

@ -21,7 +21,7 @@
/* left menu end */
/* logo start */
--logo-height: 50px;
--logo-height: 40px;
--logo-title-text-color: #fff;
/* logo end */
@ -31,14 +31,14 @@
--top-header-text-color: 'inherit';
--top-header-hover-color: #f6f6f6;
--top-header-hover-color: #215bd8;
--top-tool-height: var(--logo-height);
--top-tool-p-x: 0;
/* --tags-view-height: 35px; 开启面包屑时 */
--tags-view-height: 8px;
--tags-view-height: 16px;
/* header start */
/* tab menu start */

View File

@ -21,7 +21,13 @@
<el-form-item label="层数" prop="layersNumber" required v-if="form.type === 2">
<el-input-number v-model="form.layersNumber" :min="1" :max="3" />
</el-form-item>
<el-form-item label="编号" prop="id" required v-if="form.type === 3">
<el-form-item
label="编号"
prop="id"
required
v-if="form.type === 3"
:rules="{ required: true, message: '请选择设备编号', trigger: 'change' }"
>
<div>
<el-select
v-model="deviceInfo.deviceType"
@ -199,11 +205,12 @@ const directionChange = (e) => {
//
const deviceInfo = ref({
positionMapId: props.positionMapId,
positionMapId: '',
deviceType: ''
})
const deviceList = ref([])
const getDeviceList = async () => {
deviceInfo.value.positionMapId = props.positionMapId
deviceList.value = await MapApi.getDeviceInformationList(deviceInfo.value)
}
const deviceTypeChange = () => {

View File

@ -0,0 +1,38 @@
<template>
<Dialog v-model="dialogFormVisible" title="设备" width="600" class="text-form-dialog">
<div> 11 </div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="formSubmit"> 确认 </el-button>
</div>
</template>
</Dialog>
</template>
<script setup>
import { reactive, ref } from 'vue'
const dialogFormVisible = ref(false)
const open = (item) => {
dialogFormVisible.value = true
}
const formSubmit = () => {}
defineExpose({ open }) // open
</script>
<style lang="scss">
.text-form-dialog {
.el-dialog__header {
border-bottom: none;
}
.el-dialog__footer {
padding-bottom: 30px;
border-top: none !important;
}
}
</style>

View File

@ -0,0 +1,103 @@
<template>
<div class="layer-select">
<div class="top-list" v-if="isUnfold">
<div class="item" v-for="(item, index) in list" :key="index" @click="changeSelectList(item)">
<span class="name">{{ item.name }}</span>
<el-icon v-if="item.isShow" color="#1677FF"><View /></el-icon>
<el-icon v-else color="#444444"><Hide /></el-icon>
</div>
</div>
<div class="top-button" @click="changeUnfold">
<span class="title">图例</span>
<el-icon v-if="isUnfold" color="#98A4BF"><CaretTop /></el-icon>
<el-icon v-else color="#98A4BF"><CaretBottom /></el-icon>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue'
const list = ref([
{
labelType: 'locationPoint',
name: '库位点',
isShow: true
},
{
labelType: 'wayPoint',
name: '路径点',
isShow: true
},
{
labelType: 'devicePoint',
name: '设备点',
isShow: true
}
])
const isUnfold = ref(true)
const changeUnfold = () => {
isUnfold.value = !isUnfold.value
}
const changeSelectList = (item) => {
item.isShow = !item.isShow
}
const open = (item) => {}
defineExpose({ open }) // open
</script>
<style lang="scss">
.layer-select {
background-color: #fff;
position: fixed;
bottom: 20px;
width: 144px;
cursor: pointer;
.top-list {
.item {
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 22px;
box-sizing: border-box;
.name {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
color: rgba(0, 0, 0, 0.88);
line-height: 20px;
text-align: left;
font-style: normal;
}
}
}
.top-button {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 0;
border: 1px solid #eeeeee;
.title {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 16px;
color: #98a4bf;
line-height: 22px;
text-align: left;
font-style: normal;
}
}
}
</style>

View File

@ -1,8 +1,13 @@
<template>
<Dialog v-model="dialogFormVisible" title="文字设置" width="400" class="text-form-dialog">
<el-form :model="form">
<div class="text-form-dialog">
<el-form :model="form" :inline="true">
<el-form-item label="字体">
<el-select v-model="form.fontType" placeholder="请选择">
<el-select
v-model="form.fontFamily"
placeholder="请选择"
class="!w-100px"
@change="fontStyleChange()"
>
<el-option label="宋体" value="SimSun" />
<el-option label="黑体" value="SimHei" />
<el-option label="微软雅黑" value="Microsoft Yahei" />
@ -11,8 +16,10 @@
<el-option label="仿宋" value="FangSong" />
</el-select>
</el-form-item>
<el-form-item label="字号">
<el-input-number
@change="fontStyleChange()"
v-model="form.fontSize"
:step="1"
:min="10"
@ -21,45 +28,36 @@
/>
</el-form-item>
<el-form-item label="颜色">
<el-color-picker v-model="form.fontColor" />
<el-color-picker v-model="form.fontColor" @change="fontStyleChange()" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="dialogFormVisible = false"> 确认 </el-button>
</div>
</template>
</Dialog>
</div>
</template>
<script setup>
import { reactive, ref } from 'vue'
const dialogFormVisible = ref(false)
const formLabelWidth = '140px'
const form = reactive({
fontType: 'SimSun',
fontFamily: 'SimSun',
fontSize: '14',
fontColor: '#000000'
})
const open = (item) => {
dialogFormVisible.value = true
const fontStyleChange = () => {
emit('textFormSuccess', form)
}
defineExpose({ open }) // open
const emit = defineEmits(['textFormSuccess'])
</script>
<style lang="scss">
.text-form-dialog {
.el-dialog__header {
border-bottom: none;
}
.el-dialog__footer {
border-top: none !important;
}
background-color: #fff;
position: absolute;
top: 76px;
left: 30%;
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
padding: 18px 20px 0 20px;
border-radius: 6px;
}
</style>

View File

@ -1,19 +1,19 @@
<template>
<div>
<div class="top-tool">
<div class="top-tool-list">
<div v-for="item in state.topToolList" :key="item.id" class="top-tool-item">
<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.id === 5 || item.id === 6"
:disabled="currentItemIndex === -1"
v-if="item.switchType === 'move' || item.switchType === 'revolve'"
:disabled="!currentItemIndex"
>
<template #reference>
<div
class="tool-item"
:class="
toolbarTypeIndex === item.id
toolbarSwitchType === item.switchType
? 'tool-active'
: item.isActive
? 'right-tool-active'
@ -26,7 +26,7 @@
</div>
</template>
<!-- 位置 -->
<el-form :model="state.moveForm" v-if="item.id === 5">
<el-form :model="state.moveForm" v-if="item.switchType === 'move'">
<el-form-item label="X">
<el-input v-model="state.moveForm.x" placeholder="请输入" />
</el-form-item>
@ -38,7 +38,7 @@
</div>
</el-form>
<!-- 旋转 -->
<el-form :model="state.rotationForm" v-if="item.id === 6">
<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>
@ -47,7 +47,7 @@
</div>
</el-form>
<!-- 字体 -->
<el-form :model="state.rotationForm" v-if="item.id === 13">
<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>
@ -61,23 +61,38 @@
v-else
class="tool-item"
:class="
toolbarTypeIndex === item.id ? 'tool-active' : item.isActive ? 'right-tool-active' : ''
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.id === 3 || item.id === 10 || item.id === 17"></div>
<div
class="line"
v-if="
item.switchType === 'saveAs' ||
item.switchType === 'delete' ||
item.switchType === 'ranging'
"
></div>
</div>
</div>
<div class="right-tool-list" v-if="state.isShowToolbar">
<div
v-for="item in state.rightToolList"
:key="item.id"
:key="item.switchType"
class="tool-item"
:class="
toolbarTypeIndex === item.id ? 'tool-active' : item.isActive ? 'right-tool-active' : ''
toolbarSwitchType === item.switchType
? 'tool-active'
: item.isActive
? 'right-tool-active'
: ''
"
@click="toolbarClick(item)"
>
@ -86,14 +101,21 @@
</div>
</div>
</div>
<!-- @mousewheel.prevent="rollImg" -->
<div
class="map-box"
ref="imgWrap"
@mousewheel.prevent="rollImg"
style="overflow: hidden"
:style="{ cursor: state.cursorStyle }"
>
<div class="map-box-inner" ref="image" @mousedown.prevent="moveImg">
<div
class="map-box-inner"
ref="image"
@mousedown.stop="startDrawSelection"
@mousemove.stop="updateDrawSelection"
@mouseup.stop="endDrawSelection"
>
<img :src="imgBgObj.imgUrl" class="map-box-img" id="mapBg" />
<div
class="map-box-inner-dot"
@ -119,7 +141,6 @@
:resizable="item.resizable"
:rotatable="item.rotatable"
:lock-aspect-ratio="item.lockAspectRatio"
:handles="['tl', 'tr', 'bl', 'br', 'rot']"
style="border: none"
>
<div
@ -138,10 +159,51 @@
v-if="item.labelType === 'node'"
style="width: 100%; height: 100%; background-color: #000; border-radius: 50%"
></div>
<div
v-if="item.labelType === 'text'"
:style="{
fontSize: item.fontSize + 'px',
fontFamily: item.fontFamily,
color: item.fontColor
}"
>
{{ item.text }}
</div>
</div>
</VueDragResizeRotate>
<!-- 文档 https://github.com/a7650/vue3-draggable-resizable/blob/main/docs/document_zh.md#resizable -->
</div>
<!-- 绘制框选区域 -->
<div
v-if="state.drawSelectionArea"
:style="{
position: 'absolute',
left: `${state.drawSelectionAreaBox.x}px`,
top: `${state.drawSelectionAreaBox.y}px`,
width: `${state.drawSelectionAreaBox.width}px`,
height: `${state.drawSelectionAreaBox.height}px`,
border: '1px solid blue',
backgroundColor: 'rgba(0, 0, 255, 0.1)',
zIndex: 99999
}"
></div>
<!-- 文字输入区域 -->
<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.x + 'px',
top: state.inputBoxStyle.y + 'px'
}"
class="input-box-class"
/>
</div>
</div>
<!-- 节点编辑 -->
@ -151,19 +213,32 @@
@submitNodeSuccess="submitNodeSuccess"
/>
<!-- 文字输入弹窗 -->
<textFormToolDialog ref="textFormToolDialogRef" />
<textFormToolDialog
ref="textFormToolDialogRef"
v-if="state.textFormToolShow"
@textFormSuccess="textFormSuccess"
/>
<!-- 图层选择 -->
<layerSelectionToolDialog v-if="state.isShowLayer" ref="layerSelectionToolDialogRef" />
<!-- 设备弹窗选择 -->
<equipmentToolDialog ref="equipmentToolDialogRef" />
</template>
<script setup>
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
import editNodeProperties from './components-tool/editNodeProperties.vue'
import textFormToolDialog from './components-tool/textFormToolDialog.vue'
import equipmentToolDialog from './components-tool/equipmentToolDialog.vue'
import layerSelectionToolDialog from './components-tool/layerSelectionToolDialog.vue'
import * as MapApi from '@/api/map/map'
import cursorCollection from './cursorCollection'
defineOptions({ name: 'editMapPageRealTimeMap' })
const equipmentToolDialogRef = ref() //
const textFormToolDialogRef = ref() //
const inputBoxRef = ref() //
const message = useMessage() //
const formLoading = ref(false)
@ -241,10 +316,10 @@ const editNodePropertiesRef = ref()
const activatedHandle = (item, index) => {
// console.log('', item, index)
currentItemIndex.value = index
if (item.labelType === 'node') {
if (toolbarTypeIndex.value === 23) {
editNodePropertiesRef.value.open(item)
}
//
if (toolbarSwitchType.value === 'editNode' && item.labelType === 'node') {
editNodePropertiesRef.value.open(item)
}
}
//
@ -290,7 +365,7 @@ const backNextStep = () => {
//
const mapClick = (e) => {
if (toolbarTypeIndex.value === 22) {
if (toolbarSwitchType.value === 'drawNodes') {
//
imgList.value.push({
x: e.offsetX,
@ -308,7 +383,59 @@ const mapClick = (e) => {
currentIndex.value++
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
}
//
if (toolbarSwitchType.value === 'text') {
state.showInputBox = true
state.inputBoxStyle = {
fontSize: state.textForm.fontSize,
fontFamily: state.textForm.fontFamily,
fontColor: state.textForm.fontColor,
x: e.offsetX,
y: e.offsetY
}
//
setTimeout(() => {
inputBoxRef.value.focus()
}, 0)
}
}
//
const textFormSuccess = (form) => {
state.textForm = JSON.parse(JSON.stringify(form))
state.inputBoxStyle = {
fontSize: `${form.fontSize}`,
fontFamily: `${form.fontFamily}`,
fontColor: `${form.fontColor}`
}
}
//
const handleInputEnd = () => {
if (state.inputBoxValue) {
state.showInputBox = false
imgList.value.push({
labelType: 'text', //
mapId: '', //id
x: state.inputBoxStyle.x, //x
y: state.inputBoxStyle.y, //y
h: '', //h
w: '', //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
})
addEditHistory()
state.inputBoxValue = ''
}
}
//
const saveMap = async () => {
//
@ -346,131 +473,137 @@ const submitNodeSuccess = (item) => {
}
//
const toolbarTypeIndex = ref(0)
const toolbarSwitchType = ref('')
const state = reactive({
topToolList: [
{
id: 1,
switchType: 'open',
name: '打开',
icon: 'ep:folder-add',
isActive: false
},
{
id: 2,
switchType: 'save',
name: '保存',
icon: 'ep:folder-checked',
isActive: false
},
{
id: 3,
switchType: 'saveAs',
name: '另存为',
icon: 'ep:folder-opened',
isActive: false
},
{
id: 4,
switchType: 'choose',
name: '选择',
icon: 'ep:position',
isActive: false
},
{
id: 5,
switchType: 'move',
name: '移动',
icon: 'ep:rank',
isActive: false
},
{
id: 6,
switchType: 'revolve',
name: '旋转',
icon: 'ep:folder-add',
isActive: false
},
{
id: 7,
switchType: 'copy',
name: '复制',
icon: 'ep:document',
isActive: false
},
{
id: 8,
switchType: 'paste',
name: '粘贴',
icon: 'ep:copy-document',
isActive: false
},
{
id: 9,
switchType: 'delete',
name: '删除',
icon: 'ep:delete',
isActive: false
},
{
id: 10,
switchType: 'tools',
name: '工具',
icon: 'ep:briefcase',
isActive: false
},
{
id: 11,
switchType: 'lineLibrary',
name: '线库',
icon: 'ep:folder-add',
isActive: false
},
{
id: 12,
switchType: 'region',
name: '区域',
icon: 'ep:folder-add',
isActive: false
},
{
id: 13,
switchType: 'text',
name: '文字',
icon: 'ep:folder-add',
isActive: false
},
{
id: 14,
switchType: 'equipment',
name: '设备',
icon: 'ep:folder-add',
isActive: false
},
{
switchType: 'ranging',
name: '测距',
icon: 'ep:folder-add',
isActive: false
},
{
id: 15,
switchType: 'layer',
name: '图层',
icon: 'ep:folder-add',
isActive: false
},
{
id: 16,
switchType: 'marker',
name: '标记',
icon: 'ep:folder-add',
isActive: false
},
{
id: 17,
switchType: 'grid',
name: '网格',
icon: 'ep:folder-add',
isActive: false
},
{
id: 18,
switchType: 'larger',
name: '放大',
icon: 'ep:zoom-in',
isActive: false
},
{
id: 19,
switchType: 'smaller',
name: '缩小',
icon: 'ep:zoom-out',
isActive: false
},
{
id: 20,
switchType: 'withdraw',
name: '撤回',
icon: 'ep:top-left',
isActive: false
},
{
id: 21,
switchType: 'next',
name: '重做',
icon: 'ep:top-right',
isActive: false
@ -478,25 +611,25 @@ const state = reactive({
],
rightToolList: [
{
id: 22,
switchType: 'drawNodes',
name: '绘制节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
id: 23,
switchType: 'editNode',
name: '编辑节点',
icon: 'ep:circle-plus-filled',
isActive: false
},
{
id: 24,
switchType: 'drawRoute',
name: '绘制路线',
icon: 'ep:semi-select',
isActive: false
},
{
id: 25,
switchType: 'editRoute',
name: '编辑路线',
icon: 'ep:semi-select',
isActive: false
@ -512,32 +645,59 @@ const state = reactive({
angle: ''
}, //
copyMapItem: '', //
cursorStyle: 'auto'
cursorStyle: 'auto',
drawSelectionArea: false, //
drawSelectionAreaBox: { x: 0, y: 0, width: 0, height: 0 }, //
drawSelectionAreaStartPos: { x: 0, y: 0 }, //
drawSelectionAreaSelectedPoints: [], //list
textForm: {
fontFamily: 'SimSun',
fontSize: '14',
fontColor: '#000000'
}, //14#000000
textFormToolShow: false, //
showInputBox: false, //
inputBoxStyle: {}, //
inputBoxValue: '', //
isShowLayer: false //
})
const toolbarClick = (item) => {
let type = item.id
if (currentItemIndex.value === -1 && (type === 5 || type === 6 || type === 7 || type === 9)) {
let type = item.switchType
if (
currentItemIndex.value &&
(type === 'move' || type === 'revolve' || type === 'copy' || type === 'delete')
) {
message.warning('请先选择要操作的对象')
return
}
if (type === 8 && !state.copyMapItem) {
//
if (type === 'paste' && !state.copyMapItem) {
message.warning('请先复制对象')
return
}
if ((type === 10 || type === 13 || type === 17) && toolbarTypeIndex.value === type) {
toolbarTypeIndex.value = 0
if (
(type === 'tools' || type === 'text' || type === 'layer' || type === 'grid') &&
toolbarSwitchType.value === type
) {
toolbarSwitchType.value = ''
} else {
toolbarTypeIndex.value = type
toolbarSwitchType.value = type
}
if (toolbarSwitchType.value !== 'text') {
state.cursorStyle = `auto`
}
switch (type) {
case 1:
case 'open':
//
break
case 2:
case 'save':
//
saveMap()
break
case 3:
case 'saveAs':
// json 访
const jsonString = JSON.stringify(allHistoryList.value[currentIndex.value], null, 2)
const blob = new Blob([jsonString], { type: 'application/json' })
@ -553,59 +713,79 @@ const toolbarClick = (item) => {
message.success('下载成功')
break
case 4:
case 'choose':
//
break
case 5:
case 'move':
//
break
case 6:
case 'revolve':
break
case 7:
case 'copy':
//
state.copyMapItem = allHistoryList.value[currentIndex.value][currentItemIndex.value]
break
case 8:
case 'paste':
//
let item = JSON.parse(JSON.stringify(state.copyMapItem))
item.x = item.x + 50
item.y = item.y + 50
imgList.value.push(item)
let copyObj = JSON.parse(JSON.stringify(state.copyMapItem))
copyObj.x = copyObj.x + 50
copyObj.y = copyObj.y + 50
imgList.value.push(copyObj)
addEditHistory()
break
case 9:
case 'delete':
//
imgList.value.splice(currentItemIndex.value, 1)
addEditHistory()
break
case 10:
case 'tools':
//
if (toolbarTypeIndex.value === 10) {
if (toolbarSwitchType.value === 'tools') {
state.isShowToolbar = true
item.isActive = true
} else {
state.isShowToolbar = false
item.isActive = false
}
break
case 11:
case 'lineLibrary':
// 线
break
case 12:
case 'region':
//
break
case 13:
case 'text':
//
textFormToolDialogRef.value.open()
// if (toolbarTypeIndex.value === 13) {
// state.cursorStyle = `url('${cursorCollection.input}'),auto`
// } else {
// state.cursorStyle = `auto`
// }
if (toolbarSwitchType.value === 'text') {
state.textFormToolShow = true
state.cursorStyle = `url('${cursorCollection.input}'),auto`
} else {
state.textFormToolShow = false
state.cursorStyle = `auto`
state.textFormToolShow = false
state.showInputBox = false
state.inputBoxValue = ''
}
break
case 14:
case 'ranging':
//
break
case 15:
case 'layer':
//
if (toolbarSwitchType.value === 'layer') {
state.isShowLayer = true
item.isActive = true
} else {
state.isShowLayer = false
item.isActive = false
}
break
case 16:
case 'marker':
//
break
case 17:
case 'grid':
//
if (toolbarTypeIndex.value === 17) {
if (toolbarSwitchType.value === 'grid') {
state.isShowGrid = true
item.isActive = true
} else {
@ -613,26 +793,35 @@ const toolbarClick = (item) => {
item.isActive = false
}
break
case 18:
case 'larger':
//
break
case 19:
case 'smaller':
//
break
case 20:
case 'withdraw':
//
backPreviousStep()
break
case 21:
case 'next':
//
backNextStep()
break
case 22:
drawNodes()
case 'drawNodes':
//
break
case 23:
case 'editNode':
//
break
case 24:
case 'drawRoute':
//线
break
case 25:
case 'editRoute':
// 线
break
case 'equipment':
//
equipmentToolDialogRef.value.open()
break
}
}
@ -647,6 +836,53 @@ const rotationFormSubmit = () => {
allHistoryList.value[currentIndex.value][currentItemIndex.value].angle = state.rotationForm.angle
}
//
const startDrawSelection = (event) => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
state.drawSelectionArea = true
state.drawSelectionAreaStartPos = { x: event.offsetX, y: event.offsetY }
state.drawSelectionAreaBox = { x: event.offsetX, y: event.offsetY, width: 0, height: 0 }
}
const updateDrawSelection = (event) => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
if (state.drawSelectionArea) {
state.drawSelectionAreaBox.width = event.offsetX - state.drawSelectionAreaStartPos.x
state.drawSelectionAreaBox.height = event.offsetY - state.drawSelectionAreaStartPos.y
}
}
//
const endDrawSelection = () => {
if (toolbarSwitchType.value !== 'lineLibrary' && toolbarSwitchType.value !== 'region') return
let points = allHistoryList.value[currentIndex.value]
state.drawSelectionArea = false
state.drawSelectionAreaSelectedPoints = points.filter((point) => {
return (
point.x >=
Math.min(
state.drawSelectionAreaStartPos.x,
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
) &&
point.x <=
Math.max(
state.drawSelectionAreaStartPos.x,
state.drawSelectionAreaStartPos.x + state.drawSelectionAreaBox.width
) &&
point.y >=
Math.min(
state.drawSelectionAreaStartPos.y,
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
) &&
point.y <=
Math.max(
state.drawSelectionAreaStartPos.y,
state.drawSelectionAreaStartPos.y + state.drawSelectionAreaBox.height
)
)
})
console.log(state.drawSelectionAreaSelectedPoints, '选中的')
}
onMounted(() => {
imgList.value = [
{
@ -718,34 +954,66 @@ onMounted(() => {
box-sizing: border-box;
}
.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 {
.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 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 {
cursor: pointer;
width: 52px;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.name {
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 14px;
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;
// cursor: url('https://api.znkjfw.com/admin-api/infra/file/4/get/_png_179_1738982726561.png'),
// auto;
width: 52px;
height: 70px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px;
.name {
font-family:
PingFangSC,
@ -758,46 +1026,22 @@ onMounted(() => {
font-style: normal;
}
}
.line {
margin: 0 14px;
width: 1px;
height: 47px;
border: 1px solid #cccccc;
}
}
.tool-active {
background: #ebf1ff;
border-bottom: 2px solid #1677ff;
}
.right-tool-active {
background: #ebf1ff;
}
}
.right-tool-list {
.input-box-class {
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;
border: 1px solid #00329f;
padding: 4px;
outline: none;
}
</style>

View File

@ -705,7 +705,7 @@ const formData = ref({
skuInfo: undefined, //
skuBatch: undefined, //
skuNumber: undefined, //
priority: undefined, //
priority: 50, //
otherMsg: undefined, //
doCycle: 0, //(0:1)
doMoveAll: 0, //线/(0:1)
@ -740,7 +740,7 @@ const resetFormData = () => {
skuInfo: undefined, //
skuBatch: undefined, //
skuNumber: undefined, //
priority: undefined, //
priority: 50, //
otherMsg: undefined, //
doCycle: 0, //(0:1)
doMoveAll: 0, //线/(0:1)