无人机管理后台前端(已迁走)
张含笑
2025-10-28 0f16db42e4e331bfaf084c27ca602c275e87668d
src/views/layerManagement/components/leftList.vue
@@ -1,49 +1,60 @@
<template>
  <div class="table-overlay">
    <div class="topBar">
      <div
        v-for="(item, index) in tabData"
        :key="index"
        :class="{ 'active-tab': activeTab === index }"
        @click="activeTab = index"
      >
        {{ item.name }}
      </div>
    </div>
    <div class="searchBox">
      <el-input
        class="ztzf-input inputName"
        v-model="formData.dkbh"
        placeholder="图斑名称"
        placeholder="输入名称模糊搜索"
      ></el-input>
      <div class="searchAndReset">
        <div class="reset" @click="reset">重置</div>
        <div class="search" @click="search">搜索</div>
        <el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button class="ztzf-button" icon="el-icon-refresh" @click="reset">清空</el-button>
      </div>
    </div>
    <div class="btnGroups">
      <el-button type="primary">新增围栏</el-button>
      <el-button type="success">新增文件夹</el-button>
      <el-button type="info" @click="selectAll">全选</el-button>
      <el-button class="ztzf-button" @click="addFence">新增围栏</el-button>
      <el-button class="ztzf-button" @click="addFolder">新增文件夹</el-button>
      <el-button class="ztzf-button" @click="selectAll">全选</el-button>
    </div>
    <div class="tableListBox">
      <el-tree
        v-model="checkedKeys"
        :data="treeData"
        show-checkbox
        node-key="id"
        default-expand-all
        :props="{
          label: 'name',
          children: 'children',
        }"
      />
     <el-tree
  class="ztzf-el-tree"
  ref="treeRef"
  v-model="checkedKeys"
  :data="treeData"
  show-checkbox
  node-key="id"
  default-expand-all
  @check="handleCheck"
  :props="{
    label: 'name',
    children: 'children',
  }"
>
  <!-- 自定义节点内容 -->
  <template #default="{ node }">
    <div class="tree-node">
      <!-- 节点名称 -->
      <span>{{ node.label }}</span>
      <!-- 操作按钮组 -->
      <div class="tree-node-actions">
        <el-button icon="el-icon-location" type="text" @click="handleLocation(node)"></el-button>
        <el-button icon="el-icon-edit" type="text" @click="handleEdit(node)"></el-button>
        <el-button icon="el-icon-delete" type="text" @click="handleDelete(node)"></el-button>
      </div>
    </div>
  </template>
</el-tree>
    </div>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { treeDataApi } from '@/api/layer/index';
import { onMounted } from 'vue';
const emit = defineEmits(['update:coverData']);
const coverData = ref();
const props = defineProps(['activeName']);
const formData = {
  isPush: undefined,
  page: 1,
@@ -52,64 +63,97 @@
  dkbh: '',
  patchesName: '',
};
const tabData = ref([
  {
    name: '电子围栏',
    type: '0',
  },
  {
    name: '自定义禁飞区',
    type: '1',
  },
  {
    name: '国土空间规划',
    type: '2',
  },
]);
const activeTab = ref(0);
const handelClick = val => {
  activeTab.value = val.type;
};
const reset = () => {};
const search = () => {};
const treeData = ref([
  {
    id: 'group1',
    name: '道路裂缝识别',
    children: [
      { id: 'road1', name: '桃花路' },
      { id: 'road2', name: '洪城路' },
      { id: 'road3', name: '中山路' },
    ],
  },
  {
    id: 'group2',
    name: '电动车识别',
    children: [
      { id: 'electric1', name: '桃新大道' },
      { id: 'electric2', name: '昌南大道' },
    ],
  },
]);
const treeData = ref([]);
const treeAllData = ref([]);
// 获取数据
const gettreeDataApi = async () => {
  try {
    const res = await treeDataApi();
    treeAllData.value = res.data.data;
    console.log('接口获取数据', treeAllData.value);
    setupWatch();
  } catch (error) {
    console.error('获取数据失败:', error);
  }
};
const setupWatch = () => {
  watch(
    () => props.activeName,
    newVal => {
      const matchedCategory = treeAllData.value.find(item => item.name === newVal);
      treeData.value = matchedCategory.children;
    },
    { immediate: true }
  );
};
const checkedKeys = ref([]); // 存储勾选的节点key
const treeRef = ref(null); // 获取tree实例
const checkedNodes = ref([]); // 存储勾选的节点数据
const handleCheck = (checkedNodesData, checkedKeysData) => {
  checkedNodes.value = checkedNodesData.checkedNodes;
  coverData.value = checkedKeysData.checkedNodes;
  emit('update:coverData', coverData.value);
  // console.log('选中的节点数据:', checkedKeysData);
};
// 全选方法
const selectAll = () => {
  const allKeys = [];
  // 递归收集所有节点的id
  const collectKeys = data => {
    data.forEach(item => {
      allKeys.push(item.id);
      if (item.children) {
        collectKeys(item.children);
      }
    });
  };
  collectKeys(treeData.value);
  checkedKeys.value = allKeys;
  console.log('全选', checkedKeys.value);
  if (treeRef.value) {
    // 获取所有节点的key
    const allKeys = treeData.value.flatMap(item => [
      item.id,
      ...item.children.map(child => child.id),
    ]);
    if (checkedKeys.value.length === allKeys.length) {
      // 如果已经全选,则取消全选
      treeRef.value.setCheckedKeys([]);
      checkedNodes.value = [];
    } else {
      // 否则全选
      treeRef.value.setCheckedKeys(allKeys);
      // 获取所有节点数据
      checkedNodes.value = treeData.value.flatMap(item => [ ...item.children]);
      console.log('所有数据', checkedNodes.value);
    }
  }
};
// 定位按钮事件
const handleLocation = (node) => {
  console.log('定位操作,节点:', node);
};
// 编辑按钮事件
const handleEdit = (node) => {
  console.log('编辑操作,节点:', node.data);
   emit('update:coverData', [node.data]);
};
// 删除按钮事件
const handleDelete = (node) => {
  console.log('删除操作,节点:', node.data);
};
// 新增围栏
const addFence =()=>{
}
// 新增文件夹
const addFolder =()=>{
}
onMounted(() => {
  gettreeDataApi();
});
const changeClick = val => {};
</script>
<style scoped lang="scss">
@@ -117,53 +161,23 @@
  position: absolute;
  top: 0;
  left: 0;
  height: 99%;
  height: 95%;
  z-index: 99;
  width: 377px;
  height: 100%;
  width: 392px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.8);
  border-radius: 8px 8px 8px 8px;
  padding: 6px 10px 0 10px 10px 0 10px;
  padding: 16px 12px;
}
.topBar {
  display: flex;
  justify-content: space-between;
  color: #fff;
  font-size: 16px;
  div {
    padding: 8px 12px;
    cursor: pointer;
    position: relative;
    transition: all 0.3s ease;
    &:hover {
      color: #409eff; // 悬停颜色
    }
    &.active-tab {
      color: #409eff; // 激活颜色
      &::after {
        content: '';
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 60%;
        width: 60%;
        height: 2px;
        background-color: #409eff;
      }
    }
  }
}
.searchBox {
  display: flex;
  margin-top: 10px;
  .inputName {
    width: 184px;
    height: 32px;
  }
  .searchAndReset {
    width: 182px;
    display: flex;
@@ -181,7 +195,7 @@
    }
    .reset {
      margin-right: 7px;
      margin-left: 12px;
      background: #0d2b38;
      border-radius: 4px 4px 4px 4px;
      border: 1px solid #84cbd3;
@@ -201,9 +215,28 @@
  }
}
.btnGroups {
  margin-top: 10px;
  margin: 12px 0 14px 0;
  display: flex;
}
.tableListBox {
.tree-node {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}
.tree-node-actions {
  display: flex;
  gap: 8px; // 按钮之间的间距
  button {
    padding: 0; // 清除默认内边距
    color: #fff; // 按钮图标颜色
    &:hover {
      color: #409eff; //  hover 时的颜色
    }
  }
}
}
</style>