| | |
| | | <div |
| | | class="tableListBox" |
| | | v-loading="loading" |
| | | element-loading-background="rgba(0, 0, 0, 0.5)" |
| | | element-loading-background="rgba(0, 0, 0, 0.2)" |
| | | element-loading-text="加载中..." |
| | | > |
| | | <el-tree |
| | |
| | | node-key="id" |
| | | default-expand-all |
| | | :expand-on-click-node="false" |
| | | :check-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | highlight-current |
| | | @check="handleCheck" |
| | | :props="{ |
| | | label: 'name', |
| | |
| | | <template #default="{ node }"> |
| | | <div class="tree-node"> |
| | | <!-- 节点名称 --> |
| | | <span>{{ node.label }}</span> |
| | | <span class="nodeName">{{ node.label }}</span> |
| | | <!-- 操作按钮组 --> |
| | | <div class="tree-node-actions"> |
| | | <el-button |
| | | link |
| | | |
| | | icon="el-icon-location" |
| | | @click.stop="handleLocation(node)" |
| | | >定位</el-button> |
| | | <el-button link @click.stop="handleEdit(node)">编辑</el-button> |
| | | <el-button link @click.stop="handleDelete(node)">删除</el-button> |
| | | :disabled="node.data.level === 2 && (!node.data.children || node.data.children.length === 0)" |
| | | class="location-btn" |
| | | ></el-button> |
| | | <el-button icon="el-icon-edit" link @click.stop="handleEdit(node)"></el-button> |
| | | <el-button icon="el-icon-delete" link @click.stop="handleDelete(node)"></el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | const checkedKeys = ref([]); // 存储勾选的节点key |
| | | const treeRef = ref(null); // 获取tree实例 |
| | | const checkedNodes = ref([]); // 存储勾选的节点数据 |
| | | const props = defineProps(['activeName']); |
| | | const props = defineProps(['activeName','resetCheck']); |
| | | const formData = ref({ |
| | | isPush: undefined, |
| | | page: 1, |
| | |
| | | const gettreeDataApi = async () => { |
| | | try { |
| | | loading.value = true; |
| | | const res = await treeDataApi(); |
| | | const res = await treeDataApi({filterExpired:false}); |
| | | treeAllData.value = res.data.data; |
| | | |
| | | if(coverData.value.length===0){ |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | nextTick(() => { |
| | | if (treeRef.value) { |
| | | treeRef.value.setCheckedKeys([]); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | setupWatch(); |
| | | } catch (error) { |
| | | console.error('获取数据失败:', error); |
| | |
| | | ); |
| | | }; |
| | | const handleCheck = (checkedNodesData, checkedKeysData) => { |
| | | layerParams.value.isSingleLocating = false |
| | | const filteredNodes = checkedKeysData.checkedNodes.filter(node => node.level === 3); |
| | | checkedNodes.value = checkedNodesData.checkedNodes; |
| | | checkedNodes.value = filteredNodes |
| | | checkedKeys.value = filteredNodes.map(node => node.id); |
| | | coverData.value = filteredNodes; |
| | | emit('update:coverData', coverData.value); |
| | |
| | | ); |
| | | }; |
| | | const selectAll = () => { |
| | | layerParams.value.currentLocationFolderId = null; |
| | | layerParams.value.isSingleLocating = false |
| | | if (treeRef.value) { |
| | | const allFenceKeys = getAllFenceKeys(); |
| | | const allFenceNodes = treeData.value.flatMap(folder => folder.children); |
| | | |
| | | if (checkedKeys.value.length === allFenceKeys.length) { |
| | | // 取消全选 |
| | | treeRef.value.setCheckedKeys([]); |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | emit('update:coverData', coverData.value); |
| | | } else { |
| | | // 全选 |
| | | treeRef.value.setCheckedKeys(allFenceKeys); |
| | | checkedKeys.value = allFenceKeys; |
| | | checkedNodes.value = allFenceNodes; |
| | | coverData.value = allFenceNodes; |
| | | emit('update:coverData', coverData.value); |
| | | |
| | | } |
| | | emit('update:coverData', coverData.value); |
| | | |
| | | } |
| | | }; |
| | | // 定位按钮事件 |
| | | const handleLocation = node => { |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | const currentKey = treeRef.value.getCurrentKey(); |
| | | if (currentKey === node.data.id) { |
| | | treeRef.value.setCurrentKey(null); // 取消高亮 |
| | | } else { |
| | | treeRef.value.setCurrentKey(node.data.id); // 高亮当前节点 |
| | | } |
| | | if (node.data.level === 2) { |
| | | layerParams.value.isSingleLocating = false; |
| | | // 新增:标记当前定位的文件夹ID |
| | | layerParams.value.currentLocationFolderId = node.data.id; |
| | | } else if (node.data.level === 3) { |
| | | layerParams.value.isSingleLocating = true; |
| | | // 清空文件夹定位标识 |
| | | layerParams.value.currentLocationFolderId = null; |
| | | } |
| | | |
| | | const currentCheckedKeys = [...checkedKeys.value]; |
| | | const currentCheckedNodes = [...checkedNodes.value]; |
| | | EventBus.emit('focusOnNode', node.data); |
| | | if (node.data.level === 2) { |
| | | const folderChildren = node.data.children || []; |
| | | // const childrenIds = folderChildren.map(child => child.id); |
| | | // treeRef.value.setCheckedKeys(childrenIds); |
| | | // checkedKeys.value = childrenIds; |
| | | // checkedNodes.value = folderChildren; |
| | | coverData.value = folderChildren; |
| | | const childrenIds = folderChildren.map(child => child.id); |
| | | const newChildrenIds = childrenIds.filter(id => !currentCheckedKeys.includes(id)); |
| | | const newChildrenNodes = folderChildren.filter(child => newChildrenIds.includes(child.id)); |
| | | |
| | | const newCheckedKeys = [...new Set([...currentCheckedKeys, ...newChildrenIds])]; |
| | | const newCheckedNodes = [...currentCheckedNodes, ...newChildrenNodes]; |
| | | |
| | | treeRef.value.setCheckedKeys(newCheckedKeys); |
| | | checkedKeys.value = newCheckedKeys; |
| | | checkedNodes.value = newCheckedNodes; |
| | | coverData.value = newCheckedNodes; |
| | | emit('update:coverData', coverData.value); |
| | | } else { |
| | | // const currentNodeId = node.data.id; |
| | | // treeRef.value.setCheckedKeys([currentNodeId]); |
| | | // checkedKeys.value = [currentNodeId]; |
| | | // checkedNodes.value = [node.data]; |
| | | coverData.value = [node.data]; |
| | | } else if (!currentCheckedKeys.includes(node.data.id)) { |
| | | layerParams.value.isSingleLocating = true; |
| | | currentCheckedKeys.push(node.data.id); |
| | | currentCheckedNodes.push(node.data); |
| | | treeRef.value.setCheckedKeys(currentCheckedKeys); |
| | | checkedKeys.value = currentCheckedKeys; |
| | | checkedNodes.value = currentCheckedNodes; |
| | | coverData.value = currentCheckedNodes; |
| | | emit('update:coverData', coverData.value); |
| | | } |
| | | }; |
| | | |
| | | // 编辑按钮事件 |
| | | const handleEdit = node => { |
| | | if (node.data.level == 2) { |
| | |
| | | |
| | | // 删除按钮事件 |
| | | const handleDelete = node => { |
| | | |
| | | let id = node.data.id; |
| | | ElMessageBox.confirm('确定要删除该内容吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | |
| | | deleteFolderApi(id).then(res => { |
| | | ElMessage.success('删除成功'); |
| | | gettreeDataApi(); |
| | | // 通知父组件删除该文件夹下所有围栏的地图实体 |
| | | EventBus.emit('deleteMapEntitiesByFolderId', id); |
| | | }); |
| | | } else if (node.data.level === 3) { |
| | |
| | | deleteFenceApi(id).then(res => { |
| | | ElMessage.success('删除成功'); |
| | | gettreeDataApi(); |
| | | // 通知父组件删除对应的地图实体 |
| | | EventBus.emit('deleteMapEntityById', id); |
| | | }); |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.warning('已取消删除'); |
| | | |
| | | }); |
| | | }; |
| | | // 新增围栏 |
| | |
| | | layerParams.value.fileType = 2; |
| | | } |
| | | }; |
| | | |
| | | function uploadFlightFile(file, t) { |
| | | const fileSuffix = file.name.substring(file.name.lastIndexOf('.') + 1); |
| | | if (!['zip'].includes(fileSuffix)) { |
| | |
| | | ElMessage.success('取消同步成功'); |
| | | }); |
| | | } |
| | | |
| | | // 切换tab清空复选框的数据 |
| | | watch( |
| | | () => props.resetCheck, |
| | | (newVal) => { |
| | | if (newVal !== undefined) { |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | treeRef.value?.setCheckedKeys([]); |
| | | } |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | onMounted(() => { |
| | | failuresList(); |
| | | gettreeDataApi(); |
| | |
| | | left: 0; |
| | | height: calc(100% - 32px); |
| | | z-index: 99; |
| | | width: 382px; |
| | | width: 332px; |
| | | overflow: hidden; |
| | | background: rgba(0, 0, 0, 0.8); |
| | | background: rgba(0,0,0,0.51); |
| | | backdrop-filter: blur(4px); |
| | | border-radius: 8px 8px 8px 8px; |
| | | padding: 16px 0 16px 12px; |
| | | display: flex; |
| | |
| | | margin-top: 10px; |
| | | padding-right: 12px; |
| | | .inputName { |
| | | width: 184px; |
| | | width: 140px; |
| | | height: 32px; |
| | | } |
| | | .searchAndReset { |
| | |
| | | justify-content: right; |
| | | align-items: center; |
| | | margin-right: 10px; |
| | | .reset, |
| | | .search { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 46px; |
| | | height: 32px; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .reset { |
| | | margin-left: 12px; |
| | | background: #0d2b38; |
| | | border-radius: 4px 4px 4px 4px; |
| | | border: 1px solid #84cbd3; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #ffffff; |
| | | } |
| | | |
| | | .search { |
| | | background: #1e2d51; |
| | | border-radius: 4px 4px 4px 4px; |
| | | border: 1px solid #c5d6ff; |
| | | font-weight: 400; |
| | | font-size: 14px; |
| | | color: #ffffff; |
| | | } |
| | | } |
| | | } |
| | | .btnGroups { |
| | |
| | | overflow-y: scroll; |
| | | height: 0; |
| | | flex-grow: 1; |
| | | padding-right: 12px; |
| | | // padding-right: 12px; |
| | | :deep(.el-tree-node__content) { |
| | | height: 38px !important; |
| | | line-height: 38px !important; |
| | | height: 45px !important; |
| | | line-height: 45px !important; |
| | | // padding-left: 0 !important; |
| | | border-bottom: 1px dotted rgba(255,255,255,0.1); |
| | | } |
| | | |
| | | // 定位选中节点的背景色样式 |
| | | ::v-deep(.el-tree-node.is-current > .el-tree-node__content) { |
| | | background-color: rgba(64, 158, 255, 0.2) !important; // 浅蓝色半透明背景 |
| | | } |
| | | .isTheTerritory { |
| | | :deep() { |
| | | .el-tree-node__expand-icon { |
| | |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding-right: 12px; |
| | | width: 100%; |
| | | .nodeName { |
| | | font-size: 12px !important; |
| | | } |
| | | } |
| | | |
| | | .tree-node-actions { |
| | | display: flex; |
| | | // gap: 8px; // 按钮之间的间距 |
| | | // gap: 8px; |
| | | |
| | | button { |
| | | padding: 0; // 清除默认内边距 |
| | | // color: #fff; // 按钮图标颜色 |
| | | color: #409eff; |
| | | &:hover { |
| | | color: #409eff; // hover 时的颜色 |
| | | } |
| | | padding: 0; |
| | | color: #fff; |
| | | width: 17px; |
| | | height: 17px; |
| | | // color: #409eff; |
| | | // &:hover { |
| | | // color: #409eff; |
| | | // } |
| | | } |
| | | } |
| | | ::v-deep(.location-btn.el-button.is-link.is-disabled) { |
| | | color: #999 !important; |
| | | } |
| | | } |
| | | </style> |