浏览代码

处理节点选中

duy 2 天之前
父节点
当前提交
73c0532260
共有 1 个文件被更改,包括 72 次插入43 次删除
  1. 72 43
      src/views/data-fill/components/linkData.vue

+ 72 - 43
src/views/data-fill/components/linkData.vue

@@ -28,12 +28,12 @@
                                 :data="treeData"
                                 :props="treeProps"
                                 :default-expand-all="false"
-                        
                                 :filter-node-method="filterNode"
                                 :load="loadNode"  
                                 lazy  
                                 node-key="id"
                                 check-strictly
+                                :default-checked-keys="defaultCheckedKeys" 
                                 @node-click="handleNodeClick"
                             >
                                 <!-- 自定义节点内容,使用单选框 -->
@@ -65,6 +65,7 @@
 import { ref, watch } from 'vue'
 import wbsApi from '~api/data-fill/wbs'
 import { getArrValue, getObjValue } from 'js-fast-way'
+
 // 接收父组件传入的属性
 const props = defineProps({
     pKeyId:{
@@ -77,6 +78,7 @@ const pKeyId = ref(props.pKeyId)
 watch(() => props.pKeyId, (val) => {
     pKeyId.value = val
 })
+
 // 对话框显示状态
 const linkModal = defineModel('modelValue', {
     default: false,
@@ -92,12 +94,21 @@ const sourceData = ref([
     { id: '119739d00e974214acd85b3ad661', name: '六工区' },
     { id: 'cc10f104ddb64320ab59ac7abec9', name: '二期工程' },
 ])
+
+// 新增:默认选中的节点ID数组
+const defaultCheckedKeys = ref([])
+// 新增:用于存储所有已加载的节点数据,方便查找binded状态
+const allLoadedNodes = ref({})
+
 // 监听左侧工区变化,重新加载根节点数据
 watch(leftRadio, (newVal) => {
+    defaultCheckedKeys.value = [] // 清空默认选中
+    allLoadedNodes.value = {} // 清空已加载节点缓存
     loadRootNodes(newVal)
     selectedNodeId.value = ''
     selectedNodeData.value = null
 })
+
 // 搜索关键词
 const queryValue = ref('')
 
@@ -111,7 +122,7 @@ const selectedNodeId = ref(null)
 const treeProps = {
     label: 'name',
     children: 'children',
-    isLeaf: 'isLeaf', // 新增isLeaf字段判断是否为叶子节点
+    isLeaf: 'isLeaf',
 }
 
 // 树形数据 - 初始只存放根节点
@@ -120,73 +131,96 @@ const treeData = ref([])
 // 监听对话框显示状态
 watch(() => linkModal.value, (val) => {
     if (val) {
-        // 对话框打开时的初始化操作
         selectedNodeId.value = ''
         queryValue.value = ''
-      
+        defaultCheckedKeys.value = []
+        allLoadedNodes.value = {}
     }
 })
 
 // 加载根节点数据
 const loadRootNodes = async (workArea) => {
-  // 清空现有树形数据
   treeData.value = []
-  // 重置选中节点ID
   selectedNodeId.value = ''
   
-  if (!workArea) return // 如果没有选中工区则不加载
+  if (!workArea) return
   
   try {
-    // 加载根节点(parentId设为0表示根节点)
     const { data } = await wbsApi.getChildNodes({
       contractId: workArea,
       pKeyId: pKeyId.value || '',
-      parentId: 0, // 明确请求根节点数据
+      parentId: 0,
     })
     
-    // 设置根节点数据
-    treeData.value = getArrValue(data)
-    // 重置树形组件状态
+    const nodes = getArrValue(data)
+    treeData.value = nodes
+    // 处理根节点中的binded状态
+    handleBindedNodes(nodes)
+    
     if (treeRef.value) {
-        console.log(treeRef.value, 'treeRef.value.')
- 
-      treeRef.value.setCheckedKeys([])
+      treeRef.value.setCheckedKeys(defaultCheckedKeys.value)
     }
   } catch (error) {
     console.error('加载根节点失败:', error)
   }
 }
-// 懒加载节点方法
 
+// 新增:处理节点数据中的binded状态
+const handleBindedNodes = (nodes) => {
+    nodes.forEach(node => {
+        // 缓存所有节点数据
+        allLoadedNodes.value[node.id] = node
+        
+        // 如果节点binded为true,添加到默认选中
+        if (node.binded) {
+            defaultCheckedKeys.value.push(node.id)
+            // 如果是单选场景,直接选中最后一个binded为true的节点
+            selectedNodeId.value = node.id
+            selectedNodeData.value = node
+        }
+        
+        // 递归处理子节点(如果有的话)
+        if (node.children && node.children.length) {
+            handleBindedNodes(node.children)
+        }
+    })
+}
+
+// 懒加载节点方法
 const loadNode = async (node, resolve) => {
     const { level, data: item } = node
 
+    if (level === 0) {
+        return resolve([])
+    }
     
-  // 根节点(level:0)已通过loadRootNodes加载,直接返回空数组阻止重复请求
-  if (level === 0) {
-    return resolve([])
-  }
     let parentId = 0
     if (level !== 0) {
         const nodeData = getObjValue(item)
         parentId = nodeData?.id
-        
     }
     
-    // 获取数据
-    const { data } = await wbsApi.getChildNodes({
-        contractId: leftRadio.value || '',
-      
-        pKeyId: pKeyId.value || '',
-        parentId,
-      
-       
-       
-    })
-
-    resolve(getArrValue(data))
+    try {
+        const { data } = await wbsApi.getChildNodes({
+            contractId: leftRadio.value || '',
+            pKeyId: pKeyId.value || '',
+            parentId,
+        })
+        
+        const childNodes = getArrValue(data)
+        // 处理子节点中的binded状态
+        handleBindedNodes(childNodes)
+        // 同步更新树形组件的选中状态
+        if (treeRef.value) {
+            treeRef.value.setCheckedKeys(defaultCheckedKeys.value)
+        }
+        
+        resolve(childNodes)
+    } catch (error) {
+        console.error('加载子节点失败:', error)
+        resolve([])
+    }
 }
-// 修改加载根节点数据方法
 
 // 关闭对话框
 const closeModal = () => {
@@ -194,6 +228,8 @@ const closeModal = () => {
     selectedNodeData.value = null
     selectedNodeId.value = null
     leftRadio.value = null
+    defaultCheckedKeys.value = []
+    allLoadedNodes.value = {}
     emit('close')
 }
 
@@ -211,17 +247,14 @@ const filterNode = (value, data) => {
 // 处理节点点击事件
 const selectedNodeData = ref(null)
 const handleNodeClick = (data) => {
-    // 如果是叶子节点才允许选中
-        selectedNodeId.value = data.id
-        selectedNodeData.value = data
-
+    selectedNodeId.value = data.id
+    selectedNodeData.value = data
 }
 
 // 确认关联
 const confirmLoad = ref(false)
 const confirmLink = async () => {
     if (!selectedNodeId.value) {
-        // 提示用户未选择节点
         window?.$message?.warning('请选择节点')
         return
     }
@@ -235,14 +268,10 @@ const confirmLink = async () => {
         window.$message?.success(msg ?? '操作成功')
         closeModal()
     }
-
-    
-
 }
 </script>
 
 <style lang="scss" scoped>
-// 调整单选框与文字的对齐方式
 :deep(.el-radio) {
   vertical-align: middle;
 }