无人机管理后台前端(已迁走)
张含笑
2025-08-26 b2f7b2c66b5d5e1355de45231e4728d3a6e8127b
feat:图斑绘制
5 files modified
9 files added
855 ■■■■■ changed files
src/api/home/territory.js 9 ●●●●● patch | view | raw | blame | history
src/assets/images/home/territory/box-select.png patch | view | raw | blame | history
src/assets/images/home/territory/draw.png patch | view | raw | blame | history
src/assets/images/home/territory/newcon_box.png patch | view | raw | blame | history
src/assets/images/home/territory/no-draw.png patch | view | raw | blame | history
src/styles/common.scss 2 ●●● patch | view | raw | blame | history
src/styles/tool.scss 44 ●●●●● patch | view | raw | blame | history
src/views/job/components/DeviceJobDetailsMap.vue 1 ●●●● patch | view | raw | blame | history
src/views/resource/components/BoxSelect.vue 250 ●●●●● patch | view | raw | blame | history
src/views/resource/components/DrawPolygon.vue 312 ●●●●● patch | view | raw | blame | history
src/views/resource/components/FunButton.vue 151 ●●●●● patch | view | raw | blame | history
src/views/resource/components/spotDetails.vue 69 ●●●● patch | view | raw | blame | history
src/views/resource/patchManagement.vue 15 ●●●● patch | view | raw | blame | history
src/views/resource/patchTypeManagement.vue 2 ●●●●● patch | view | raw | blame | history
src/api/home/territory.js
New file
@@ -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,
  })
}
src/assets/images/home/territory/box-select.png
src/assets/images/home/territory/draw.png
src/assets/images/home/territory/newcon_box.png
src/assets/images/home/territory/no-draw.png
src/styles/common.scss
@@ -1,7 +1,7 @@
// 全局变量
@import './variables.scss';
@import './base.scss';
@import './tool.scss';
a {
  text-decoration: none;
  color: #333;
src/styles/tool.scss
New file
@@ -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);
        }
    }
}
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'
src/views/resource/components/BoxSelect.vue
New file
@@ -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>
src/views/resource/components/DrawPolygon.vue
New file
@@ -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>
src/views/resource/components/FunButton.vue
New file
@@ -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>
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>
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' ? '图斑详情' : '图斑编辑';
}
// 跳转至图斑类型管理页面
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