feat: 优化地区管理地图操作

This commit is contained in:
XieYongHong 2023-10-25 18:52:30 +08:00
parent d5fe1702d2
commit dda03a03f4
6 changed files with 303 additions and 16 deletions

View File

@ -25,7 +25,7 @@
"event-source-polyfill": "^1.0.31",
"global": "^4.4.0",
"jetlinks-store": "^0.0.3",
"jetlinks-ui-components": "^1.0.34-2",
"jetlinks-ui-components": "^1.0.34-3",
"js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"less": "^4.1.3",

View File

@ -22,6 +22,8 @@ import '@vuemap/vue-amap/dist/style.css';
import { getAMapUiPromise } from './utils';
import { useSystem } from '@/store/system';
const emit = defineEmits('init')
const system = useSystem();
interface AMapProps {
style?: CSSProperties;
@ -65,8 +67,9 @@ const initMap = (e: any) => {
if (isOpenUi.value) {
getAMapUI();
}
emit('init', e)
};
</script>
<style lang="less" scoped>
</style>
</style>

View File

@ -4132,7 +4132,7 @@ export default [
sortIndex: 12,
url: '/system/region',
icon: 'FormOutlined',
showPage: ['region'],
showPage: ['area'],
permissions: [],
buttons: [
{
@ -4140,7 +4140,7 @@ export default [
name: "新增",
permissions: [
{
permission: "region",
permission: "area",
actions: [
"save"
]
@ -4152,7 +4152,7 @@ export default [
name: "删除",
permissions: [
{
permission: "region",
permission: "area",
actions: [
"delete"
]
@ -4164,7 +4164,7 @@ export default [
name: "编辑",
permissions: [
{
permission: "region",
permission: "area",
actions: [
"save"
]

View File

@ -1,7 +1,99 @@
<template>
<AMapComponent>
<div class="region-map">
<AMapComponent
@init="initMap"
>
<el-amap-polygon
v-if="overlay.type === 'polygon'"
:key="JSON.stringify(overlay.path || [])"
:editable="overlay.editable"
:path="overlay.path"
:visible="visible"
@addnode="polygonDraw"
@adjust="polygonDraw"
@init="overlaysInit"
@removenode="polygonDraw"
/>
<el-amap-circle
v-else-if="overlay.type === 'circle'"
:key="`${overlay.radius}_${JSON.stringify(overlay.path || [])}`"
:center="overlay.path"
:editable="overlay.editable"
:radius="overlay.radius"
:visible="visible"
@adjust="circleDraw"
@init="overlaysInit"
/>
<el-amap-rectangle
v-else-if="overlay.type === 'rectangle'"
:key="JSON.stringify(overlay.path || [])"
:bounds="overlay.path"
:editable="overlay.editable"
:visible="visible"
@adjust="rectangleDraw"
@init="overlaysInit"
/>
<el-amap-mouse-tool
v-else-if="overlay.type === 'create' && toolType"
:type="toolType"
@draw="toolDraw"
/>
</AMapComponent>
<div v-show="overlay.editable || overlay.type === 'create'" class="map-tool">
<div class="map-tool-content">
<div class="tool-item-group">
<div class="tool-item">
<j-tooltip title="双击保存描点" >
<AIcon type="QuestionCircleOutlined" />
</j-tooltip>
</div>
</div>
<div class="tool-item-group">
<div :class="{'tool-item': true, 'active': toolType === 'rectangle'}" @click="() => { drawOverlays('rectangle') }">
<j-tooltip title="矩形" >
<AIcon type="icon-huajuxing" />
</j-tooltip>
</div>
<div :class="{'tool-item': true, 'active': toolType === 'circle'}" @click="() => { drawOverlays('circle') }">
<j-tooltip title="圆" >
<AIcon type="icon-draw-circle" />
</j-tooltip>
</div>
<div :class="{'tool-item': true, 'active': toolType === 'polygon'}" @click="() => { drawOverlays('polygon') }">
<j-tooltip title="多边形" >
<AIcon type="icon-huaduobianxing" />
</j-tooltip>
</div>
</div>
<!-- <div class="tool-item-group">-->
<!-- <div class="tool-item">-->
<!-- <j-tooltip title="缩放" >-->
<!-- <AIcon type="GetwayOutlined" />-->
<!-- </j-tooltip>-->
<!-- </div>-->
<!-- <div class="tool-item">-->
<!-- <j-tooltip title="旋转" >-->
<!-- <AIcon type="GetwayOutlined" />-->
<!-- </j-tooltip>-->
<!-- </div>-->
<!-- </div>-->
<div class="tool-item-group">
<div :class="{'tool-item': true, 'disabled': historyList.length <= 1 }" @click="cancel">
<j-tooltip title="撤销" >
<AIcon type="RollbackOutlined" />
</j-tooltip>
</div>
<div class="tool-item">
<j-tooltip title="删除" @click="deleteOverlays">
<AIcon type="DeleteOutlined" />
</j-tooltip>
</div>
</div>
</div>
</div>
</div>
</AMapComponent>
</template>
<script name="RegionMap" setup>
@ -9,13 +101,204 @@ const props = defineProps({
path: {
type: Array,
default: () => []
}
},
radius: {
type: Number,
default: 0
},
type: {
type: String,
default: 'polygon'
},
})
const emit = defineEmits('')
const emit = defineEmits('dragend')
const MapRef = ref()
const toolType = ref('')
const historyList = ref([])
const overlay = reactive({
type: props.type,
path: props.path,
center: [],
editable: false,
status: 0 // 0 1
})
const visible = computed(() => {
return true
})
const setHistory = (data) => {
if (historyList.value.length > 10) {
historyList.value.shift()
}
historyList.value.push(data)
}
const initMap = (e) => {
MapRef.value = e
}
const polygonDraw = (e) => {
const target = e.target
const path = target.getPath()
setHistory({
type: 'polygon',
toolType: toolType.value,
editable: true,
path: path.map(item => [item.lng, item.lat]),
})
}
const circleDraw = (e) => {
setHistory({
type: 'circle',
toolType: toolType.value,
editable: true,
path: [e.lnglat.lng, e.lnglat.lat],
radius: e.radius
})
}
const rectangleDraw = (e) => {
const northEast = e.bounds.getNorthEast()
const southWest = e.bounds.getSouthWest()
const path = [
[southWest.lng, southWest.lat],
[northEast.lng, northEast.lat]
]
setHistory({
type: 'rectangle',
toolType: toolType.value,
editable: true,
path: path,
})
}
const overlaysInit = (e) => {
if (MapRef.value) {
MapRef.value.setFitView(e)
}
}
const drawOverlays = (e) => {
overlay.type = 'create'
toolType.value = e
}
const toolDraw = (e) => {
if (toolType.value === 'circle') {
overlay.path = e.center
overlay.radius = e.radius
} else {
overlay.path = e
}
overlay.editable = true
overlay.type = toolType.value
setHistory({
type: toolType.value,
toolType: toolType.value,
editable: overlay.editable,
path: overlay.path,
radius: overlay.radius
})
}
const deleteOverlays = () => {
overlay.type = 'create'
overlay.editable = false
toolType.value = ''
setHistory({
type: 'create',
toolType: '',
editable: false,
path: [],
radius: 0
})
}
const cancel = () => {
if (historyList.value.length > 1) {
historyList.value.pop()
}
const oldData = historyList.value[historyList.value.length - 1]
if (oldData) {
overlay.type = oldData.type
overlay.editable = oldData.editable
overlay.path = oldData.path
overlay.radius = oldData.radius
toolType.value = oldData.toolType
}
}
</script>
<style scoped>
<style lang="less" scoped>
.region-map {
position: relative;
height: 100%;
.map-tool{
position: absolute;
top: 20%;
right: 20px;
.map-tool-content {
display: flex;
gap: 24px;
flex-direction: column;
.tool-item-group {
display: flex;
flex-direction: column;
border: 1px solid #e3e3e3;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 16px rgba(#000, .15);
.tool-item {
padding: 4px 6px;
color: #333;
font-size: 16px;
&:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
&:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
&:not(:first-child) {
border-top: 1px solid #e3e3e3;
}
&.active {
background-color: var(--ant-primary-color);
color: #fff;
}
&.disabled {
cursor: not-allowed !important;
background-color: #efefef;
> span {
cursor: not-allowed !important;
color: #666;
}
}
}
}
}
}
}
</style>

View File

@ -12,7 +12,7 @@
<LeftTree />
</div>
<div class="right">
<Map />
<Map :path="path" type="create" />
</div>
</div>
</full-page>
@ -29,6 +29,7 @@ import FullPage from "components/Layout/FullPage.vue";
const searchValue = ref()
const visible = ref<boolean>(false)
const current = ref<any>({})
const path = ref([[121.5273285, 31.21515044], [121.5293285, 31.21515044], [121.5293285, 31.21915044], [121.5273285, 31.21515044]])
const onSearch = () => {

View File

@ -3738,10 +3738,10 @@ jetlinks-store@^0.0.3:
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
jetlinks-ui-components@^1.0.34-2:
version "1.0.34-2"
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-2.tgz#8acd9f5dd4e5baa89703391620c80545c60ea98d"
integrity sha512-Z8/TRoJut1CuGsXXkzUYwvmKdQ1FhvXc46uK308M76Ezv4iJIGphwt1ancqVst0+WRBWoG6ps2ZsBbqCSQB7Rg==
jetlinks-ui-components@^1.0.34-3:
version "1.0.34-3"
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-3.tgz#c4f8182ce7419db40ed6d937ab0a7040bfb1549a"
integrity sha512-9jzzGOIR5ICCBdCVYfQoWyZCIFcauLuvIF+WN/djR1glC4lsBdegN06HpzxcGMfsJlWODxzjRXEq+UDNqiL4zg==
dependencies:
"@vueuse/core" "^9.12.0"
"@vueuse/router" "^9.13.0"