From b2f7b2c66b5d5e1355de45231e4728d3a6e8127b Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Tue, 26 Aug 2025 16:37:05 +0800
Subject: [PATCH] feat:图斑绘制
---
src/assets/images/home/territory/newcon_box.png | 0
src/views/resource/components/spotDetails.vue | 69 +++
src/assets/images/home/territory/no-draw.png | 0
src/api/home/territory.js | 9
src/views/resource/patchManagement.vue | 15
src/views/resource/patchTypeManagement.vue | 2
src/views/resource/components/BoxSelect.vue | 250 ++++++++++++++++
src/styles/common.scss | 2
src/styles/tool.scss | 44 ++
src/views/job/components/DeviceJobDetailsMap.vue | 1
src/views/resource/components/FunButton.vue | 151 ++++++++++
src/views/resource/components/DrawPolygon.vue | 312 ++++++++++++++++++++
src/assets/images/home/territory/box-select.png | 0
src/assets/images/home/territory/draw.png | 0
14 files changed, 831 insertions(+), 24 deletions(-)
diff --git a/src/api/home/territory.js b/src/api/home/territory.js
new file mode 100644
index 0000000..b88ce8b
--- /dev/null
+++ b/src/api/home/territory.js
@@ -0,0 +1,9 @@
+import request from '@/axios';
+// 更新图斑数据
+export const sdfwUpdate = params => {
+ return request({
+ url: `/drone-device-core/patches/api/v1/Patches/sdfwUpdate`,
+ method: 'put',
+ data: params,
+ })
+}
\ No newline at end of file
diff --git a/src/assets/images/home/territory/box-select.png b/src/assets/images/home/territory/box-select.png
new file mode 100644
index 0000000..fa9d02f
--- /dev/null
+++ b/src/assets/images/home/territory/box-select.png
Binary files differ
diff --git a/src/assets/images/home/territory/draw.png b/src/assets/images/home/territory/draw.png
new file mode 100644
index 0000000..a225c87
--- /dev/null
+++ b/src/assets/images/home/territory/draw.png
Binary files differ
diff --git a/src/assets/images/home/territory/newcon_box.png b/src/assets/images/home/territory/newcon_box.png
new file mode 100644
index 0000000..483bf7a
--- /dev/null
+++ b/src/assets/images/home/territory/newcon_box.png
Binary files differ
diff --git a/src/assets/images/home/territory/no-draw.png b/src/assets/images/home/territory/no-draw.png
new file mode 100644
index 0000000..d20e974
--- /dev/null
+++ b/src/assets/images/home/territory/no-draw.png
Binary files differ
diff --git a/src/styles/common.scss b/src/styles/common.scss
index 86695a3..b5114eb 100644
--- a/src/styles/common.scss
+++ b/src/styles/common.scss
@@ -1,7 +1,7 @@
// 全局变量
@import './variables.scss';
@import './base.scss';
-
+@import './tool.scss';
a {
text-decoration: none;
color: #333;
diff --git a/src/styles/tool.scss b/src/styles/tool.scss
new file mode 100644
index 0000000..6c367bd
--- /dev/null
+++ b/src/styles/tool.scss
@@ -0,0 +1,44 @@
+.proof-custom-add-polygon {
+ position: absolute;
+ left: 20px;
+ background: rgba(0, 0, 0, .6);
+ white-space: nowrap;
+ border-radius: 4px;
+
+ &::after {
+ content: '';
+ position: absolute;
+ left: -3px;
+ top: calc(50% - 2px);
+ width: 0;
+ height: 0;
+ border-top: 4px solid rgba(0, 0, 0, .6);
+ border-left: 4px solid rgba(0, 0, 0, .6);
+ border-right: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ transform: rotate(-45deg);
+ }
+}
+
+
+.create-draw-canvas-menu,
+.planar-menu-panel {
+ width: 'fit-content';
+ background: url("@/assets/images/home/territory/newcon_box.png") no-repeat center / 100% 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ color: #fff;
+ font-size: 16px;
+ z-index: 99;
+
+ div {
+ padding: 5px 10px;
+ cursor: pointer;
+ font-weight: bold;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/views/job/components/DeviceJobDetailsMap.vue b/src/views/job/components/DeviceJobDetailsMap.vue
index ee2ce6b..ffbc284 100644
--- a/src/views/job/components/DeviceJobDetailsMap.vue
+++ b/src/views/job/components/DeviceJobDetailsMap.vue
@@ -1,6 +1,7 @@
<template>
<div id="deviceJobDetailsMap" class="ztzf-cesium">
</div>
+
</template>
<script setup>
import * as Cesium from 'cesium'
diff --git a/src/views/resource/components/BoxSelect.vue b/src/views/resource/components/BoxSelect.vue
new file mode 100644
index 0000000..87a9858
--- /dev/null
+++ b/src/views/resource/components/BoxSelect.vue
@@ -0,0 +1,250 @@
+<template>
+ <div></div>
+</template>
+
+<script setup>
+import * as Cesium from 'cesium'
+import { ElMessage } from 'element-plus'
+
+let curPolygonPosition = []
+let savePolygonPosition = []
+let curPolygon = null
+let curPolygonEntity = null
+let curPolygonObj = null
+let menuPanel = null
+let saveMenuPanel = null
+
+const viewInstance = inject('viewInstance')
+const homeViewer = inject('homeViewer')
+
+const updateBoxSelect = inject('updateBoxSelect')
+
+function preventDefault(event) {
+ event.preventDefault()
+
+ return
+}
+
+function init() {
+ // draw.drawPlane();
+ curPolygon = new Cesium.PolygonHierarchy()
+ curPolygonEntity = new Cesium.Entity()
+
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = true
+
+ viewInstance.value.addLeftClickEvent(null, addPlanerPointEvent, 'drawCustomPolygon')
+ viewInstance.value.addRightClickEvent(null, addPlanarMenuEvent, 'drawCustomPolygon')
+ viewInstance.value.addMouseHandler(null, mouseMoveEvent, 'drawCustomPolygon')
+}
+
+function mouseMoveEvent(movement, viewer) {
+ const mouseInfo = viewInstance.value.getMouseInfoAll(movement.endPosition)
+
+ const { x, y } = mouseInfo.windowPosition
+
+ if (!menuPanel) {
+ menuPanel = createMenuPanel()
+ viewer.container.appendChild(menuPanel)
+ }
+
+ menuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`
+
+ if (
+ curPolygonObj &&
+ mouseInfo.surfacePosition &&
+ mouseInfo.surfacePosition != null &&
+ curPolygonPosition.length >= 1
+ ) {
+ curPolygonPosition.pop()
+ curPolygonPosition.push(mouseInfo.surfacePosition)
+
+ curPolygon.positions.pop()
+ curPolygon.positions.push(mouseInfo.surfacePosition)
+ }
+}
+
+function addPlanerPointEvent(click, pick) {
+ const { position } = click
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position)
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo)
+}
+
+function addPlanarMenuEvent(click, pick, viewer) {
+ if (savePolygonPosition.length <= 2) {
+ ElMessage.warning('当前绘制无法形成面,请继续绘制或取消绘制!!')
+
+ return
+ }
+ const { position } = click
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position)
+
+ remove()
+ removeMenuPanel()
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo)
+
+ const { x, y } = position
+ saveMenuPanel = createSaveMenuPanel()
+ saveMenuPanel.addEventListener('click', saveMenuClickEvent)
+ saveMenuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`
+ viewer.container.appendChild(saveMenuPanel)
+}
+
+function createSaveMenuPanel() {
+ const menuPanel = document.createElement('div')
+ menuPanel.className = 'planar-menu-panel'
+
+ const arr = [
+ { title: '保存框选', class: 'save-draw' },
+ { title: '清除框选', class: 'anew-draw' },
+ ]
+
+ arr.forEach(item => {
+ const title = document.createElement('div')
+ title.innerText = item.title
+ title.className = item.class
+ menuPanel.appendChild(title)
+ })
+
+ return menuPanel
+}
+
+const emit = defineEmits(['upDateBoxSelect'])
+
+function saveMenuClickEvent(e) {
+ const className = e.target.className
+ if (className === 'save-draw') {
+ emit('upDateBoxSelect')
+ updateBoxSelect(savePolygonPosition)
+ }
+ if (className == 'anew-draw') {
+ cancel()
+ }
+
+ removeSaveMenuPanel()
+}
+
+function removeSaveMenuPanel() {
+ if (saveMenuPanel) {
+ homeViewer.value.container?.removeChild(saveMenuPanel)
+ saveMenuPanel.removeEventListener('click', saveMenuClickEvent)
+ saveMenuPanel = null
+ }
+}
+
+function createMenuPanel() {
+ const menuPanel = document.createElement('div')
+ menuPanel.className = 'planar-menu-panel'
+
+ const title = document.createElement('div')
+ title.innerText = '左击选择点位,右击结束'
+ title.className = 'proof-custom-add-polygon'
+ menuPanel.appendChild(title)
+
+ return menuPanel
+}
+
+function removeMenuPanel() {
+ if (menuPanel) {
+ homeViewer.value.container?.removeChild(menuPanel)
+ menuPanel = null
+ }
+}
+
+function drawCustomPolygon(point) {
+ if (curPolygonPosition.length == 0) {
+ curPolygonPosition.push(point.surfacePosition.clone())
+ curPolygon.positions.push(point.surfacePosition.clone())
+ }
+
+ savePolygonPosition.push(point.wgs84SurfacePosition)
+ curPolygonPosition.push(point.surfacePosition.clone())
+ curPolygon.positions.push(point.surfacePosition.clone())
+
+ if (!curPolygonObj) {
+ curPolygonEntity.polyline = {
+ width: 2,
+ material: Cesium.Color.WHITE,
+ clampToGround: false,
+ }
+
+ curPolygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
+ return curPolygonPosition
+ }, false)
+
+ curPolygonEntity.polygon = {
+ hierarchy: new Cesium.CallbackProperty(function () {
+ return curPolygon
+ }, false),
+
+ material: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.4),
+ clampToGround: false,
+ }
+ curPolygonEntity.name = 'customProofPolygon'
+
+ curPolygonEntity._id = 'customProofPolygon'
+ curPolygonObj = homeViewer.value.entities.add(curPolygonEntity)
+ }
+}
+
+function clearPlanar() {
+ homeViewer.value.entities.remove(curPolygonObj)
+ curPolygonObj = null
+ curPolygon = null
+ curPolygonEntity = null
+ curPolygonPosition = []
+ savePolygonPosition = []
+}
+
+function remove() {
+ viewInstance.value.removeLeftClickEvent('drawCustomPolygon')
+ viewInstance.value.removeRightClickEvent('drawCustomPolygon')
+ viewInstance.value.removeMouseHandler('drawCustomPolygon')
+}
+
+function cancel() {
+ remove()
+ removeMenuPanel()
+ clearPlanar()
+
+ init()
+}
+
+onMounted(() => {
+ document.addEventListener('contextmenu', preventDefault)
+
+ init()
+})
+
+onBeforeUnmount(() => {
+ document.removeEventListener('contextmenu', preventDefault)
+
+ remove()
+ removeMenuPanel()
+ removeSaveMenuPanel()
+ clearPlanar()
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = false
+})
+</script>
+
+<style lang="scss" scoped>
+p {
+ text-indent: 2em;
+ color: #ffffff;
+ font-size: 18px;
+}
+
+.export-btns {
+ margin-top: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+
+ .el-button {
+ background-color: transparent !important;
+ }
+}
+</style>
diff --git a/src/views/resource/components/DrawPolygon.vue b/src/views/resource/components/DrawPolygon.vue
new file mode 100644
index 0000000..3880ce9
--- /dev/null
+++ b/src/views/resource/components/DrawPolygon.vue
@@ -0,0 +1,312 @@
+<template>
+ <div></div>
+</template>
+
+<script setup>
+import * as Cesium from 'cesium'
+
+import { ElMessage } from 'element-plus'
+import { sdfwUpdate } from '@/api/home/territory'
+
+let curPolygonPosition = []
+let savePolygonPosition = []
+let curPolygon = null
+let curPolygonEntity = null
+let curPolygonObj = null
+
+let menuPanel = null
+let saveMenuPanel = null
+
+const selectionIds = inject('selectionIds')
+const clearSelect = inject('clearSelect')
+// const getTableList = inject('getTableList')
+
+const viewInstance = inject('viewInstance')
+const homeViewer = inject('homeViewer')
+
+function preventDefault(event) {
+ event.preventDefault()
+
+ return
+}
+
+function init() {
+ // let draw = new Draw(homeViewer.value);
+ // draw.drawPlane();
+ curPolygon = new Cesium.PolygonHierarchy()
+ curPolygonEntity = new Cesium.Entity()
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = true
+
+ viewInstance.value.addLeftClickEvent(null, addPlanerPointEvent, 'drawCustomPolygon')
+ viewInstance.value.addRightClickEvent(null, addPlanarMenuEvent, 'drawCustomPolygon')
+ viewInstance.value.addMouseHandler(null, mouseMoveEvent, 'drawCustomPolygon')
+}
+
+function mouseMoveEvent(movement, viewer) {
+ const mouseInfo = viewInstance.value.getMouseInfoAll(movement.endPosition)
+
+ const { x, y } = mouseInfo.windowPosition
+
+ if (!menuPanel) {
+ menuPanel = createMenuPanel()
+ viewer.container.appendChild(menuPanel)
+ }
+
+ menuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`
+
+ if (
+ curPolygonObj &&
+ mouseInfo.surfacePosition &&
+ mouseInfo.surfacePosition != null &&
+ curPolygonPosition.length >= 1
+ ) {
+ curPolygonPosition.pop()
+ curPolygonPosition.push(mouseInfo.surfacePosition)
+
+ curPolygon.positions.pop()
+ curPolygon.positions.push(mouseInfo.surfacePosition)
+ }
+}
+
+function addPlanerPointEvent(click, pick) {
+ const { position } = click
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position)
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo)
+}
+
+function addPlanarMenuEvent(click, pick, viewer) {
+ if (savePolygonPosition.length <= 2) {
+ ElMessage.warning('当前绘制无法形成面,请继续绘制或取消绘制!!')
+
+ return
+ }
+ const { position } = click
+
+ const mouseInfo = viewInstance.value.getMouseInfoAll(position)
+
+ remove()
+ removeMenuPanel()
+
+ if (mouseInfo.surfacePosition && mouseInfo.surfacePosition != null) drawCustomPolygon(mouseInfo)
+
+ const { x, y } = position
+ saveMenuPanel = createSaveMenuPanel()
+ saveMenuPanel.addEventListener('click', saveMenuClickEvent)
+ saveMenuPanel.style.transform = `translate3d(${x}px, ${y}px, 0)`
+ viewer.container.appendChild(saveMenuPanel)
+}
+
+function createSaveMenuPanel() {
+ const menuPanel = document.createElement('div')
+ menuPanel.className = 'planar-menu-panel'
+
+ const arr = [
+ { title: '提交绘制', class: 'save-draw' },
+ { title: '重新绘制', class: 'anew-draw' },
+ ]
+
+ arr.forEach(item => {
+ const title = document.createElement('div')
+ title.innerText = item.title
+ title.className = item.class
+ menuPanel.appendChild(title)
+ })
+
+ return menuPanel
+}
+
+function saveMenuClickEvent(e) {
+ const className = e.target.className
+ if (className === 'save-draw') {
+ updatePolygon()
+ }
+ if (className == 'anew-draw') {
+ cancel()
+ }
+
+ removeSaveMenuPanel()
+}
+
+function removeSaveMenuPanel() {
+ if (saveMenuPanel) {
+ homeViewer.value.container?.removeChild(saveMenuPanel)
+ saveMenuPanel.removeEventListener('click', saveMenuClickEvent)
+ saveMenuPanel = null
+ }
+}
+
+function createMenuPanel() {
+ const menuPanel = document.createElement('div')
+ menuPanel.className = 'planar-menu-panel'
+
+ const title = document.createElement('div')
+ title.innerText = '左击选择点位,右击结束'
+ title.className = 'proof-custom-add-polygon'
+ menuPanel.appendChild(title)
+
+ return menuPanel
+}
+
+function removeMenuPanel() {
+ if (menuPanel) {
+ homeViewer.value.container?.removeChild(menuPanel)
+ menuPanel = null
+ }
+}
+
+function drawCustomPolygon(point) {
+ if (curPolygonPosition.length == 0) {
+ curPolygonPosition.push(point.surfacePosition.clone())
+ curPolygon.positions.push(point.surfacePosition.clone())
+ }
+
+ savePolygonPosition.push(point.wgs84SurfacePosition)
+ curPolygonPosition.push(point.surfacePosition.clone())
+ curPolygon.positions.push(point.surfacePosition.clone())
+
+ if (!curPolygonObj) {
+ curPolygonEntity.polyline = {
+ width: 2,
+ material: Cesium.Color.WHITE,
+ clampToGround: false,
+ }
+
+ curPolygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
+ return curPolygonPosition
+ }, false)
+
+ curPolygonEntity.polygon = {
+ hierarchy: new Cesium.CallbackProperty(function () {
+ return curPolygon
+ }, false),
+
+ material: Cesium.Color.fromCssColorString('#00ffff').withAlpha(0.4),
+ clampToGround: false,
+ }
+ curPolygonEntity.name = 'customProofPolygon'
+
+ curPolygonEntity._id = 'customProofPolygon'
+ curPolygonObj = homeViewer.value.entities.add(curPolygonEntity)
+ }
+}
+
+function clearPlanar() {
+ homeViewer.value.entities.remove(curPolygonObj)
+ curPolygonObj = null
+ curPolygon = null
+ curPolygonEntity = null
+ curPolygonPosition = []
+ savePolygonPosition = []
+}
+
+function remove() {
+ viewInstance.value.removeLeftClickEvent('drawCustomPolygon')
+ viewInstance.value.removeRightClickEvent('drawCustomPolygon')
+ viewInstance.value.removeMouseHandler('drawCustomPolygon')
+}
+
+const emit = defineEmits(['upDateDrawState'])
+
+function updatePolygon() {
+ let polygon = savePolygonPosition.reduce((pre, cur) => {
+ pre.push(`${cur.lng} ${cur.lat}`)
+ return pre
+ }, [])
+ polygon.push(polygon[0])
+ console.log('绘制',`POLYGON((${polygon.join(',')}))`);
+ElMessage.success('重新绘制图斑成功!!')
+if (selectionIds.value) {
+ emit('upDateDrawState')
+ selectionIds.value = null
+ clearSelect()
+ }
+
+// 接口
+ // sdfwUpdate({
+ // ids: selectionIds.value,
+ // sdfw: `POLYGON((${polygon.join(',')}))`,
+ // })
+ // .then(res => {
+ // if (selectionIds.value) {
+ // emit('upDateDrawState')
+ // selectionIds.value = null
+ // // clearSelect()
+ // }
+
+ // if (res.data.code !== 0) return ElMessage.error(res.message)
+ // ElMessage.success('重新绘制图斑成功!!')
+
+ // // getTableList()
+ // })
+ // .catch(e => {
+ // cancel()
+ // })
+}
+
+function cancel() {
+ remove()
+ removeMenuPanel()
+ clearPlanar()
+
+ init()
+}
+
+onMounted(() => {
+ document.addEventListener('contextmenu', preventDefault)
+
+ init()
+})
+
+onBeforeUnmount(() => {
+ document.removeEventListener('contextmenu', preventDefault)
+
+ remove()
+ removeMenuPanel()
+ removeSaveMenuPanel()
+ clearPlanar()
+
+ homeViewer.value.scene.globe.depthTestAgainstTerrain = false
+})
+</script>
+
+<style lang="scss" scoped>
+p {
+ text-indent: 2em;
+ color: #ffffff;
+ font-size: 18px;
+}
+
+.export-btns {
+ margin-top: 44px;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+
+ .el-button {
+ background-color: transparent !important;
+ }
+}
+.proof-custom-add-polygon {
+ position: absolute;
+ left: 20px;
+ background: rgba(0, 0, 0, .6);
+ white-space: nowrap;
+ border-radius: 4px;
+
+ &::after {
+ content: '';
+ position: absolute;
+ left: -3px;
+ top: calc(50% - 2px);
+ width: 0;
+ height: 0;
+ border-top: 4px solid rgba(0, 0, 0, .6);
+ border-left: 4px solid rgba(0, 0, 0, .6);
+ border-right: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ transform: rotate(-45deg);
+ }
+}
+</style>
diff --git a/src/views/resource/components/FunButton.vue b/src/views/resource/components/FunButton.vue
new file mode 100644
index 0000000..5484226
--- /dev/null
+++ b/src/views/resource/components/FunButton.vue
@@ -0,0 +1,151 @@
+<template>
+ <div class="fun-button-container">
+ <template v-for="(item, index) in tooltipList" :key="index">
+ <el-popover
+ effect="dark"
+ placement="right"
+ :trigger="item.isClick ? 'click' : 'hover'"
+ popper-class="function-popover"
+ v-if="item.show"
+ >
+ <div>
+ <div>{{ item.label[Number(item.isSelected)] }}</div>
+ </div>
+ <template #reference v-if="item.show">
+ <div
+ :class="['currency-box', { 'actived-blue': item.isSelected && item.isSelectColor && item.showActive }]"
+ @click="item.event(item, index)"
+ >
+ <img :src="item.icon[Number(item.isSelected)]" alt="_icon" />
+ </div>
+ </template>
+ </el-popover>
+ </template>
+ </div>
+
+ <BoxSelect v-if="isShowBoxSelect" @upDateBoxSelect="upDateBoxSelect" />
+ <DrawPolygon v-if="isShowDrawPolygon" @upDateDrawState="upDateDrawState" />
+</template>
+
+<script setup>
+import { useStore } from 'vuex'
+import drawPng from '@/assets/images/home/territory/draw.png'
+import noDrawPng from '@/assets/images/home/territory/no-draw.png'
+import boxSelectPng from '@/assets/images/home/territory/box-select.png'
+
+import BoxSelect from './BoxSelect.vue'
+import DrawPolygon from './DrawPolygon.vue'
+
+const isBoxSelect = defineModel('isBoxSelect')
+const isDrawPolygon = defineModel('isDrawPolygon')
+const isShowBoxSelect = ref(false)
+const isShowDrawPolygon = ref(false)
+
+const isDrawPolygonSelect = ref(false)
+
+watch(isBoxSelect, newVal => {
+ if (newVal === false) {
+ isShowBoxSelect.value = newVal
+
+ setBoxSelect(null, 1, newVal)
+ }
+})
+
+watch(isDrawPolygon, newVal => {
+ if (newVal === false) {
+ isShowDrawPolygon.value = newVal
+
+ setDrawState(null, 0, newVal)
+ }
+})
+
+const tooltipList = ref([
+ {
+ showActive: true,
+ label: ['重新绘制', '取消绘制'],
+ isSelectColor: true,
+ isSelected: false,
+ icon: [drawPng, noDrawPng],
+ event: setDrawState,
+ show: isDrawPolygon,
+ },
+
+ {
+ showActive: true,
+ label: ['框选', '取消框选'],
+ isSelectColor: true,
+ isSelected: false,
+ icon: [boxSelectPng, boxSelectPng],
+ event: setBoxSelect,
+ show: isBoxSelect,
+ },
+])
+
+function setDrawState(value, index, show = null) {
+ if (show != null) {
+ tooltipList.value[index].isSelected = show
+ } else {
+ tooltipList.value[index].isSelected = !tooltipList.value[index].isSelected
+ }
+
+ isShowDrawPolygon.value = tooltipList.value[index].isSelected
+ isDrawPolygonSelect.value = tooltipList.value[index].isSelected
+}
+
+function upDateDrawState(show = false) {
+ setDrawState(null, 0, show)
+}
+
+function setBoxSelect(value, index, show = null) {
+ if (show != null) {
+ tooltipList.value[index].isSelected = show
+ } else {
+ tooltipList.value[index].isSelected = !tooltipList.value[index].isSelected
+ }
+
+ isShowBoxSelect.value = tooltipList.value[index].isSelected
+}
+
+function upDateBoxSelect(show = false) {
+ setBoxSelect(null, 1, show)
+}
+
+defineExpose({
+ upDateDrawState,
+ isDrawPolygonSelect,
+})
+</script>
+
+<style lang="scss" scoped>
+.fun-button-container {
+ position: absolute;
+ top: 50px;
+ left: 30%;
+ transform: translate(100%, 0);
+}
+
+.currency-box {
+ width: 45px;
+ height: 45px;
+ border-radius: 3px;
+ background: url('@/assets/images/home/territory/newcon_box.png');
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ cursor: pointer;
+ margin-bottom: 8px;
+ pointer-events: all;
+
+ img {
+ width: 31px;
+ // height: 31px;
+ }
+}
+
+.actived-blue {
+ background-image: none;
+ // background-color: #409eff;
+ background-color: rgba(23, 124, 198, 0.7);
+}
+</style>
diff --git a/src/views/resource/components/spotDetails.vue b/src/views/resource/components/spotDetails.vue
index 38f75ee..7d9e9d2 100644
--- a/src/views/resource/components/spotDetails.vue
+++ b/src/views/resource/components/spotDetails.vue
@@ -1,5 +1,5 @@
<template>
- <el-dialog title="图斑详情" append-to-body v-model="uploadPatchDialog" width="70%" align-center>
+ <el-dialog :title="props.title" append-to-body v-model="uploadPatchDialog" width="80%" align-center>
<div class="container">
<!-- 信息展示区 -->
<div class="infoBox">
@@ -18,8 +18,8 @@
<!-- 图斑列表 -->
<div class="table-overlay">
<div class="table-content">
- <div>图斑列表</div>
- <el-table ref="polygonTableEle" :data="tableData" border style="width: 100%" @row-click="handleLocationPolygon">
+ <div class="tabname">图斑列表</div>
+ <el-table ref="polygonTableEle" highlight-current-row :data="tableData" border style="width: 100%" @row-click="handleLocationPolygon">
<el-table-column type="index" label="序号" width="80">
<template #default="{ $index }">
{{ ($index + 1).toString().padStart(2, '0') }}
@@ -30,7 +30,7 @@
<el-table-column label="操作" width="100" align="center">
<template #default="scope">
<el-button type="text">删除</el-button>
- <el-button type="text" @click="handleSelectionChange(scope.row)">编辑</el-button>
+ <el-button type="text" @click.stop="handleSelectionChange(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
@@ -38,13 +38,15 @@
<el-pagination
background
layout="prev, pager, next"
- :total="50"
+ :total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
+ <!--绘制按钮-->
+ <FunButton ref="funButtonEle" v-model:isBoxSelect="isBoxSelect" v-model:isDrawPolygon="isDrawPolygon" ></FunButton>
<!-- 地图 -->
<div id="spotMap" class="ztzf-cesium" v-show="uploadPatchDialog"></div>
</div>
@@ -65,17 +67,28 @@
import * as Cesium from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import { ref, watch, onBeforeUnmount } from 'vue';
+import FunButton from '@/views/resource/components/FunButton.vue';
const uploadPatchDialog = defineModel('show');
+const props=defineProps(['title'])
const polygonTableEle = ref(null)
let publicCesiumInstance = null;
let viewer = null;
const viewInstance = shallowRef(null);
const homeViewer = shallowRef(null);
let tbJwdList = [];
+let total = ref(0)
// 当前选中的图斑面数据
let nowSelectObj = ref({})
// 记录上一次点击高亮
let lastHighlightRow = null
+// 功能按钮区域相关:编辑图斑等
+const funButtonEle = ref(null)
+const isBoxSelect = ref(false)
+const isDrawPolygon = ref(false)
+// 选中了哪些图斑
+const selectionIds = ref(null)
+// 当前在编辑状态的异常图斑
+let curCustomPolygon = null
const infoList = ref([
{ name: '文件名称', value: '55', field: 'job_info_num' },
{ name: '图斑类型', value: 'ee', field: 'name' },
@@ -116,6 +129,7 @@
...item,
dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
}));
+ total.value = res.data.data.pagination.total
// 先清空地图现有图斑
tbJwdList = [];
viewer.entities.removeAll(); // 清除所有实体
@@ -178,10 +192,7 @@
viewInstance.value.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting')
});
};
-// 编辑,选中当前图斑
-const handleSelectionChange =(row)=>{
- heightlightSpot(row)
-}
+
// 高亮当前选中图斑,并定位
const handleLocationPolygon = (data, Deselect) => {
heightlightSpot(data)
@@ -228,6 +239,7 @@
if (Nowentity && Nowentity.polygon) {
Nowentity.polygon.material = Cesium.Color.RED.withAlpha(0.3)
Nowentity.polygon.outlineColor = Cesium.Color.RED
+
}
homeViewer.value.scene.camera.setView({
@@ -235,6 +247,33 @@
})
lastHighlightRow = data
}
+// 清空选中的数据
+const clearSelect =()=>{
+lastHighlightRow = null
+selectionIds.value = null
+}
+// 编辑
+const handleSelectionChange =(row)=>{
+ console.log('编辑',row);
+ let curRowIsSelect = row
+ selectionIds.value = row.id
+ curRowIsSelect && handleLocationPolygon(row)
+ if (row.is_exception == 2 && curRowIsSelect) {
+ isDrawPolygon.value = true
+ funButtonEle.value.upDateDrawState(true)
+ handleLocationPolygon(row)
+ // clearSelect()
+ // curCustomPolygon = row
+ // ElMessage.warning('该图斑数据异常,请在地图区域重新绘制!!')
+ }else{
+ isDrawPolygon.value = false
+ }
+
+}
+provide('selectionIds', selectionIds)
+provide('homeViewer', homeViewer)
+provide('viewInstance', viewInstance)
+provide('clearSelect', clearSelect)
// 销毁
const destroyMap = () => {
if (viewer) {
@@ -338,11 +377,10 @@
position: absolute;
top: 0;
left: 0;
- width: 30%;
- height: 100%;
+ width: 23%;
+ height: 95%;
z-index: 999;
- // background: rgba(255, 255, 255, 0.9);
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ // background: rgba(31, 62, 122, 0.85);
padding: 10px;
display: flex;
flex-direction: column;
@@ -351,7 +389,9 @@
.table-content {
display: flex;
flex-direction: column;
- height: 90%;
+ height: 95%;
+ .tabname {
+ color: #102441;}
}
.pagination-container {
@@ -372,4 +412,5 @@
height: 100%;
width: 100%;
}
+
</style>
diff --git a/src/views/resource/patchManagement.vue b/src/views/resource/patchManagement.vue
index 1a9b072..ee9d276 100644
--- a/src/views/resource/patchManagement.vue
+++ b/src/views/resource/patchManagement.vue
@@ -17,9 +17,9 @@
</template>
<template #menu="scope">
- <el-button type="primary" text icon="el-icon-view" @click="uploadPatch(scope.row)">详情
+ <el-button type="primary" text icon="el-icon-view" @click="uploadPatch(scope.row,'detail')">详情
</el-button>
- <el-button type="primary" text icon="el-icon-edit" @click="uploadPatch(scope.row)">编辑
+ <el-button type="primary" text icon="el-icon-edit" @click="uploadPatch(scope.row,'edit')">编辑
</el-button>
<el-button type="primary" text icon="el-icon-delete" @click="handleDebug(scope.row)">删除
</el-button>
@@ -30,7 +30,7 @@
<avue-form ref="form" :option="debugOption" v-model="debugForm" @submit="handleSubmit" />
</el-dialog>
<!-- 图斑详情 -->
- <SpotDetails v-model:show="uploadPatchDialog"></SpotDetails>
+ <SpotDetails v-model:show="uploadPatchDialog" :title="spotDetailsTitle"></SpotDetails>
<!-- <patchDetails ref="patchDetails" /> -->
</basic-container>
</template>
@@ -44,7 +44,7 @@
import func from '@/utils/func'
import patchDetails from '@/views/resource/components/patchDetails.vue'
import SpotDetails from '@/views/resource/components/spotDetails.vue';
-
+const spotDetailsTitle = ref('');
const store = useStore()
const router = useRouter()
@@ -351,9 +351,10 @@
})
}
-// 上传图斑
-const uploadPatch = () => {
- uploadPatchDialog.value = true
+// 图斑详情/编辑
+const uploadPatch = (row, type = 'detail') => {
+ uploadPatchDialog.value = true;
+ spotDetailsTitle.value = type === 'detail' ? '图斑详情' : '图斑编辑';
}
// 跳转至图斑类型管理页面
diff --git a/src/views/resource/patchTypeManagement.vue b/src/views/resource/patchTypeManagement.vue
index 221278f..94ee57c 100644
--- a/src/views/resource/patchTypeManagement.vue
+++ b/src/views/resource/patchTypeManagement.vue
@@ -265,8 +265,6 @@
loading.value = true
listOfSpotTypesApi(searchparams).then(res => {
const resData = res.data.data
- console.log('列表',resData.records);
-
page.value.total = resData.total
data.value = resData.records
loading.value = false
--
Gitblit v1.9.3