无人机管理后台前端(已迁走)
chenyao
2025-09-22 904c1a7f4e277f0ab5b9745cacdd5651d87db06e
Merge remote-tracking branch 'origin/feature/v6.0/6.0.3' into feature/v6.0/6.0.3
3 files modified
286 ■■■■ changed files
src/views/resource/components/DrawPolygon.vue 5 ●●●●● patch | view | raw | blame | history
src/views/resource/components/spotDetails.vue 263 ●●●● patch | view | raw | blame | history
src/views/system/userinfo.vue 18 ●●●● patch | view | raw | blame | history
src/views/resource/components/DrawPolygon.vue
@@ -214,7 +214,7 @@
  viewInstance.value.removeMouseHandler('drawCustomPolygon');
}
const emit = defineEmits(['upDateDrawState']);
const emit = defineEmits(['upDateDrawState',]);
function updatePolygon() {
  let polygon = savePolygonPosition.reduce((pre, cur) => {
@@ -222,7 +222,7 @@
    return pre;
  }, []);
  polygon.push(polygon[0]);
  console.log('绘制', `POLYGON((${polygon.join(',')}))`);
  // 接口
  sdfwUpdate({
      ids: selectionIds.value,
@@ -244,6 +244,7 @@
      })
}
function cancel() {
  remove();
  removeMenuPanel();
src/views/resource/components/spotDetails.vue
@@ -66,14 +66,12 @@
              :row-class-name="tableRowClassName"
              :data="tableData"
              @row-click="handleLocationPolygon"
              @current-change="handleTableRowChange"
            >
              <el-table-column type="index" align="center" :width="pxToRemNum(30)" label="序号">
                <template #default="{ $index }">
                  {{
                    ($index + 1 + (params.page - 1) * params.pageSize).toString().padStart(2, '0')
                  }}
                </template>
               <template #default="{ $index }">
                {{ ($index + 1).toString().padStart(2, '0') }}
              </template>
              </el-table-column>
              <el-table-column prop="dkbh" align="center"  label="图斑名称" show-overflow-tooltip />
              <el-table-column prop="is_exception" :width="pxToRemNum(50)" align="center" label="图斑状态">
@@ -94,20 +92,7 @@
                </template>
              </el-table-column>
            </el-table>
            <div class="pagination-container">
              <el-pagination
                :current-page="params.page"
                :page-size="params.pageSize"
                background
                layout="prev, pager, next, ..."
                :pager-count="3"
                prev-text="上一页"
                next-text="下一页"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
              />
            </div>
          </div>
        </div>
        <!--绘制按钮-->
@@ -116,6 +101,7 @@
          ref="drawPolygonRef"
          v-if="isEditing"
          @upDateDrawState="handleUpDateDrawState"
        />
        <!-- 完成/取消 -->
        <div class="btnGroups" v-if="props.title === '图斑编辑'">
@@ -130,6 +116,7 @@
</template>
<script setup>
import { flyVisual } from '@/utils/cesium/mapUtil'
import { pxToRem, pxToRemNum } from '@/utils/rem'
import DrawPolygon from '@/views/resource/components/DrawPolygon.vue';
import { ElMessage, ElMessageBox } from 'element-plus';
@@ -252,59 +239,30 @@
  page: 1,
  pageSize: 10,
});
const isInit = ref(true);
// 图斑管理表格
const getTableList = () => {
  const requestParams = {
    patchesInfoId: props.detailid,
    page: params.value.page,
    pageSize: params.value.pageSize,
  };
  tableMapListApi(requestParams).then(res => {
    tableData.value = res.data.data.records?.map(item => ({
  AlltableMapListApi(requestParams).then(res => {
    tableData.value = res.data.data?.map(item => ({
      ...item,
      dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
    }));
    total.value = res.data.data.total || res.data.data.length;
    tbJwdList = [];
    viewer?.entities.removeAll();
    if (!AlltableData.value) {
    if (!tableData.value) {
      viewInstance.value?.flyToContour();
    } else {
      entitiesAddSpot();
    }
  });
};
// 所有图斑数据
const getAlltableMapListApi = () => {
  loading.value = true;
  const requestParams = {
    patchesInfoId: props.detailid,
  };
  AlltableMapListApi(requestParams).then(res => {
    AlltableData.value = res.data.data?.map(item => ({
      ...item,
      dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
    }));
    tbJwdList = [];
    viewer?.entities.removeAll();
    if (AlltableData.value.length < 1) {
      viewInstance.value?.flyToContour();
    } else {
      entitiesAddSpot();
    }
    loading.value = false;
  });
};
const handleSizeChange = val => {
  params.value.pageSize = val;
  params.value.page = 1;
  getTableList();
};
const handleCurrentChange = val => {
  params.value.page = val;
  getTableList();
};
// 地图
const initMap = () => {
@@ -324,35 +282,52 @@
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewInstance.value.switchContour(true);
};
// 仅弹框初始化时执行的定位逻辑
const initMapLocation = () => {
  if (tbJwdList.length === 0 || !homeViewer.value) return;
  // 计算所有图斑的包围球(用于初始化定位)
  const allPositions = tbJwdList.flatMap(item =>
    Cesium.Cartesian3.fromDegreesArray(item.grouped)
  );
  const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions);
  // 初始化定位(仅执行一次)
  homeViewer.value.camera.flyToBoundingSphere(boundingSphere, {
    duration: 0,
    offset: new Cesium.HeadingPitchRange(
      Cesium.Math.toRadians(0),
      Cesium.Math.toRadians(-90)
    ),
  });
};
// 初始化所有图斑
const entitiesAddSpot = () => {
  viewer?.entities.removeAll();
  AlltableData.value.forEach(item => {
    // 取出当中经纬度
  tbJwdList = []; // 重置经纬度列表
  tableData.value.forEach(item => {
    const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g);
    if (!numbersWithCommas) return;
    // 绘制图斑
    const grouped = numbersWithCommas.map(item => Number(item));
    // 为框选存储对比值
    tbJwdList.push({
      ...item,
      grouped: grouped,
    });
    viewInstance.value.removeById('polygon_dk' + item.id);
    // 根据 is_exception 设置颜色
    const color =
      item.is_exception == 2 ? Cesium.Color.RED.withAlpha(0.5) : Cesium.Color.YELLOW.withAlpha(0.5);
    const outlineColor = item.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW;
    const grouped = numbersWithCommas.map(Number);
    tbJwdList.push({ ...item, grouped }); // 存储经纬度用于后续操作
    // 绘制图斑(保留原有逻辑,仅移除定位相关代码)
    const fillColor = item.is_exception === 2
      ? Cesium.Color.RED.withAlpha(0.5)
      : Cesium.Color.YELLOW.withAlpha(0.5);
    const outlineColor = item.is_exception === 2
      ? Cesium.Color.RED
      : Cesium.Color.YELLOW;
    homeViewer.value?.entities?.add({
      id: 'polygon_dk' + item.id,
      id: `polygon_dk${item.id}`,
      customType: 'pattern_spot_polygon',
      customInfo: {
        ...item,
      },
      customInfo: item,
      polygon: {
        hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(grouped)),
        material: color,
        material: fillColor,
        outline: true,
        outlineColor: outlineColor,
        outlineWidth: 2,
@@ -362,23 +337,22 @@
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(grouped),
        width: 2,
        material: color,
        material: outlineColor,
        clampToGround: true,
      },
      zIndex: 99,
    });
    if (tbJwdList.length > 0) {
      const positions = tbJwdList.flatMap(item => Cesium.Cartesian3.fromDegreesArray(item.grouped));
      const boundingSphere = Cesium.BoundingSphere.fromPoints(positions);
      homeViewer.value?.camera.flyToBoundingSphere(boundingSphere, {
        duration: 0,
        offset: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90)),
      });
    }
    viewInstance.value?.removeLeftClickEvent('spotHighlighting');
    viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting');
  });
  // 仅在初始化阶段执行定位(关键:通过isInit控制)
  if (isInit.value) {
    initMapLocation();
    isInit.value = false; // 初始化完成,后续不再执行定位
  }
  // 保留图斑点击高亮事件(原有逻辑不变)
  viewInstance.value?.removeLeftClickEvent('spotHighlighting');
  viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting');
};
// 高亮当前选中图斑,并定位
@@ -441,16 +415,12 @@
  updateMapSpotInfo(nowEntity);
}
// 更新上一个和这一个信息
function updateMapSpotInfo(nowEntity) {
  const nowData = nowEntity.customInfo;
  if (!nowEntity) return;
  if (nowEntity.customInfo.id === lastEntity?.customInfo.id) return;
  // 设置新的
  nowEntity.polygon.material = Cesium.Color.RED.withAlpha(0);
  nowEntity.polyline.material = Cesium.Color.RED;
  // 重置上一个
  if (lastEntity) {
    const lastData = lastEntity.customInfo;
    const originalFillColor =
@@ -459,7 +429,6 @@
        : Cesium.Color.YELLOW.withAlpha(0.5);
    const originalOutlineColor =
      lastData.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW;
    lastEntity.polygon.material = originalFillColor;
    lastEntity.polygon.outlineColor = originalOutlineColor;
    lastEntity.polyline.material = originalOutlineColor;
@@ -467,23 +436,20 @@
  lastEntity = nowEntity;
  const numbersWithCommas = nowData.dkfw.match(/\d+(\.\d+)?/g);
  if (numbersWithCommas) {
    // 解析经纬度数组
    const groupedArr = numbersWithCommas.reduce((acc, val, index, src) => {
      if (index % 2 === 0) acc.push(src.slice(index, index + 2));
      return acc;
    }, []);
    const polygonCenter = getCenterPoint(groupedArr);
    // 相机定位
    homeViewer.value.scene.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(
        Number(polygonCenter.lng),
        Number(polygonCenter.lat),
        1500
      ),
      zIndex: 100,
    const positionsData = [];
    for (let i = 0; i < numbersWithCommas.length; i += 2) {
      const lon = Number(numbersWithCommas[i]);
      const lat = Number(numbersWithCommas[i + 1]);
      positionsData.push([lon, lat, 10]);
    }
    flyVisual({
      positionsData: positionsData,
      viewer: homeViewer.value,
      multiple: 15,
    });
  }
  // flyMapSpot(nowEntity?.customInfo)
}
// 清空选中的数据
const clearSelect = () => {
@@ -492,26 +458,31 @@
  viewer?.entities.removeAll();
};
// 编辑
const handleSelectionChange = row => {
  let curRowIsSelect = row;
  curRowIsSelect && handleLocationPolygon(row);
  // 如果是同一个图斑且正在编辑,则取消编辑
  if (selectionIds.value === row.id && isEditing.value) {
    isEditing.value = false;
    handleUpDateDrawState(false);
    selectionIds.value = null;
    selectionList.value = [];
    return;
  }
  // 定位到选中的图斑
  handleLocationPolygon(row);
  // 仅异常图斑可编辑
  if (row.is_exception !== 2) {
    ElMessage.warning('仅异常图斑支持编辑绘制');
    return;
  }
  // 设置编辑状态
  selectionIds.value = row.id;
  selectionList.value = row;
  if (isEditing.value) {
    //当前已编辑 → 取消编辑(关闭绘制、重置状态)
    isEditing.value = false;
    handleUpDateDrawState(false); // 通知DrawPolygon取消绘制
  } else {
    // 当前未编辑 → 开启编辑(仅异常图斑可编辑)
    if (row.is_exception === 2 && curRowIsSelect) {
      isEditing.value = true;
      handleUpDateDrawState(true); // 通知DrawPolygon开启绘制
    } else {
      ElMessage.warning('仅异常图斑支持编辑绘制');
      isEditing.value = false;
    }
  }
  isEditing.value = true;
  handleUpDateDrawState(true);
};
const handleUpDateDrawState = show => {
  isEditing.value = show; // 同步编辑状态
@@ -522,7 +493,7 @@
  }
};
// 删除
const handleDelete = row => {
const handleDelete = (row) => {
  ElMessageBox.confirm('确认删除当前行图斑?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
@@ -531,9 +502,27 @@
    deletePatches({ ids: row.id }).then(res => {
      if (res.data.code !== 0) return ElMessage.warning('删除失败');
      ElMessage.success('删除成功');
      getTableList();
      getspotManagementTableApi();
      getAlltableMapListApi();
      tableData.value = tableData.value.filter(item => item.id !== row.id);
      //从地图上移除对应的图斑实体
      const entityId = `polygon_dk${row.id}`;
      viewer?.entities.removeById(entityId);
      const exceptionCountItem = infoList.value.find(item => item.name === '异常图斑数量');
      if (exceptionCountItem && row.is_exception === 2) {
        exceptionCountItem.value = Math.max(0, parseInt(exceptionCountItem.value) - 1);
      }
      const totalCountItem = infoList.value.find(item => item.name === '图斑数量');
      if (totalCountItem) {
        totalCountItem.value = Math.max(0, parseInt(totalCountItem.value) - 1);
      }
      // 清除选中状态
      if (selectionIds.value === row.id) {
        selectionIds.value = null;
        selectionList.value = [];
        isEditing.value = false;
        handleUpDateDrawState(false);
      }
    });
  });
};
@@ -602,18 +591,23 @@
  publicCesiumInstance = null;
};
watch(uploadPatchDialog, newVal => {
  if (newVal) {
    isInit.value = true;
    setTimeout(() => {
      initMap();
      getTableList();
      getAlltableMapListApi();
      initMap();
      getTableList();
      getspotManagementTableApi();
    }, 0);
  } else {
 tableData.value = [];
    isEditing.value = false;
    handleUpDateDrawState(false);
    destroyMap();
    isInit.value = false;
    clearSelect();
  }
  refreshonload();
});
@@ -634,6 +628,10 @@
  font-size: 16px !important;
  color: #363636 !important;
}
:global(.spotDialog .el-dialog__body) {
    padding: 2rem 2rem 0 !important;
  }
.container {
  display: flex;
  flex-direction: column;
@@ -794,7 +792,7 @@
    // 表格主体
    .el-table__body {
      tr:hover > td {
        background-color: rgba(0, 0, 0, 0.6) !important;
        background-color: rgba(64, 158, 255,0.3) !important;
      }
      td {
@@ -804,7 +802,8 @@
    // 选中行
    .current-row td {
      background-color: rgba(0, 0, 0, 0.6) !important;
      background-color: rgba(64, 158, 255,0.3) !important;
    }
  }
  :deep(.el-table__body) {
src/views/system/userinfo.vue
@@ -44,7 +44,7 @@
            <el-form-item label="姓名:">
              <el-input
                class="ztzf-input"
                :style="{ width: pxToRem(230) }"
                :style="{ width: pxToRem(350) }"
                v-model="userInfo.realName"
                disabled
              />
@@ -300,6 +300,7 @@
  margin: 16px;
  padding: 10px;
  background-color: #ffffff;
  height: 100%;
}
.titleBoxs {
  margin: 0 24px;
@@ -319,26 +320,25 @@
:deep(.el-form-item__label) {
  color: #000 !important;
}
:deep(.el-button) {
  width: 150px !important;
}
// :deep(.el-button) {
//   width: 150px !important;
// }
.info {
  display: flex;
  justify-content: space-between;
  justify-content: center;
  align-items: center;
  padding: 0 80px 0 50px;
  .section:first-child{
  margin-right: 50px;}
}
.password {
  padding: 0 120px 0 50px;
}
.butn {
  // position: absolute;
  // bottom: 20px;
  // left: 50%;
  // transform: translate(-50%);
  display: flex;
  justify-content: center;
  cursor: pointer;
  img {
    width: 96px;
    height: 32px;