瀏覽代碼

feat(data-fill): 新增跨节点移动功能

duy 2 月之前
父節點
當前提交
fab204b4e4
共有 2 個文件被更改,包括 317 次插入0 次删除
  1. 279 0
      src/views/data-fill/components/jumpTreeDialog.vue
  2. 38 0
      src/views/data-fill/wbs.vue

+ 279 - 0
src/views/data-fill/components/jumpTreeDialog.vue

@@ -0,0 +1,279 @@
+<template>
+    <hc-new-dialog v-model="moveModal" is-table title="跨节点移动" widths="72rem" @close="closeModal">
+        <hc-page-split>
+            <template #left>
+                <hc-card scrollbar>
+                    <div class="checkbox-container">
+                        <el-checkbox
+                            v-model="checkAll"
+                            :indeterminate="isIndeterminate"
+                            @change="handleCheckAllChange"
+                        >
+                            <span class="font-800">全选</span>
+                        </el-checkbox>
+                        <el-checkbox-group
+                            v-model="checkedCities"
+                            class="checkbox-group"
+                            @change="handleCheckedCitiesChange"
+                        >
+                            <el-checkbox 
+                                v-for="city in cities" 
+                                :key="city" 
+                                :label="city" 
+                                :value="city"
+                                class="checkbox-item"
+                            >
+                                {{ city }}
+                            </el-checkbox>
+                        </el-checkbox-group>
+                    </div>
+                </hc-card>
+            </template>
+            <hc-card class="tree-card">
+                <template #search>
+                    <div class="flex-1">
+                        <el-input v-model="searchInput" placeholder="请输入" />
+                    </div>
+                    <div class="ml-2">
+                        <el-button       
+                            hc-btn
+                            type="primary"       
+                            @click="searchClick"
+                        >
+                            搜索
+                        </el-button>
+                    </div>
+                </template>
+                <!-- 添加懒加载树 -->
+                <el-scrollbar class="tree-scrollbar mt-3" style="height: 100%;">
+                    <el-tree
+                        ref="treeRef"
+                        node-key="id"
+                        :data="treeData"
+                        :props="treeProps"
+                        :load="treeLoadNode"
+                        lazy
+                        :show-checkbox="true"
+                        :check-strictly="true"
+                        :check-on-click-node="true"
+                       
+                        highlight-current
+                        @check="handleCheckChange"
+                    >
+                        <template #default="{ node, data }">
+                            <span class="custom-tree-node">
+                                <span>{{ node.label }}</span>
+                                <span v-if="data.code" class="ml-2 text-gray-400">({{ data.code }})</span>
+                            </span>
+                        </template>
+                    </el-tree>
+                </el-scrollbar>
+            </hc-card>
+        </hc-page-split>
+    </hc-new-dialog>
+</template>
+
+<script setup> 
+import { nextTick, ref, watch } from 'vue'
+import { getArrValue, getObjValue } from 'js-fast-way'
+import queryApi from '~api/data-fill/query'
+// 接收父组件传入的属性
+const props = defineProps({
+  contractId: {
+    type: String,
+    default: '',
+  },
+  classType: {
+    type: String,
+    default: '',
+  },
+  authBtnTabKey: {
+    type: String,
+    default: '',
+  },
+})
+//事件
+const emit = defineEmits(['close', 'save'])
+const contractId = ref(props.contractId)
+const classType = ref(props.classType) 
+const authBtnTabKey = ref(props.authBtnTabKey)
+//监听
+watch(() => [
+
+    props.contractId,
+    props.classType,
+    props.authBtnTabKey,
+], ([cid, clas, tab]) => {
+    contractId.value = cid
+    classType.value = clas
+    authBtnTabKey.value = tab
+})
+const moveModal = defineModel('modelValue', {
+    default: false,
+})
+const closeModal = ()=>{
+    moveModal.value = false
+   
+    emit('close')
+}
+
+const checkAll = ref(false)
+const isIndeterminate = ref(true)
+const checkedCities = ref([])
+const cities = ['Shanghai', 'Beijing']
+
+const handleCheckAllChange = (val) => {
+  checkedCities.value = val ? cities : []
+  isIndeterminate.value = false
+}
+const handleCheckedCitiesChange = (value) => {
+  const checkedCount = value.length
+  checkAll.value = checkedCount === cities.length
+  isIndeterminate.value = checkedCount > 0 && checkedCount < cities.length
+}
+const searchInput = ref('')
+
+// 树相关
+const treeRef = ref(null)
+const treeData = ref([])
+const currentNode = ref(null)
+
+// 树配置
+const treeProps = {
+  label: 'title',
+  children: 'children',
+  isLeaf: 'notExsitChild',
+}
+
+// 加载节点数据
+
+const treeLoadNode = async (node, resolve) => {
+ 
+    const { level, data: item } = node
+    
+    let contractIdRelation = '',
+        parentId = '',
+        primaryKeyId = ''
+    if (level !== 0) {
+        const nodeData = getObjValue(item)
+        contractIdRelation = nodeData?.contractIdRelation || ''
+        parentId = contractIdRelation ? nodeData?.primaryKeyId : nodeData?.id
+        primaryKeyId = nodeData?.id || ''
+    }
+    //获取数据
+    const { data } = await queryApi.queryWbsTreeData({
+        contractId: contractId.value || '',
+        contractIdRelation,
+        primaryKeyId,
+        parentId,
+        // classifyType: authBtnTabKey.value,
+        classifyType: classType.value,
+        tableOwner: authBtnTabKey.value,
+        dataTime:new Date(),
+    })
+
+
+    resolve(getArrValue(data))
+}
+// 节点点击事件
+const handleCheckChange = (data, checked) => {
+  // 确保只能选中一个节点
+  const checkedNodes = treeRef.value.getCheckedNodes()
+  if (checkedNodes.length > 1) {
+    // 取消之前选中的节点
+    checkedNodes.forEach(node => {
+      if (node.id !== data.id) {
+        treeRef.value.setChecked(node, false)
+      }
+    })
+  }
+  currentNode.value = checked ? data : null
+  console.log('当前选中节点:', currentNode.value)
+}
+
+// 搜索功能
+const searchClick = () => {
+  if (!searchInput.value) {
+    window.$message.warning('请输入搜索关键词')
+    return
+  }
+  // TODO: 实现搜索逻辑
+  console.log('搜索关键词:', searchInput.value)
+}
+</script>
+
+<style lang="scss" scoped>
+.checkbox-container {
+    display: flex;
+    flex-direction: column;
+    gap: 10px;
+
+    .checkbox-group {
+        display: flex;
+        flex-direction: column;
+        gap: 10px;
+    }
+
+    .checkbox-item {
+        height: 32px;
+        display: flex;
+        align-items: center;
+    }
+}
+
+.custom-tree-node {
+  display: flex;
+  align-items: center;
+  font-size: 14px;
+  
+  .el-icon {
+    margin-right: 4px;
+  }
+}
+
+:deep(.el-tree-node__content) {
+  height: 32px;
+  
+  &:hover {
+    background-color: var(--el-tree-node-hover-bg-color);
+  }
+}
+
+
+:deep(.el-tree) {
+  // 自定义复选框样式使其看起来像单选框
+  .el-checkbox {
+    .el-checkbox__inner {
+      border-radius: 50%;
+      &::after {
+        transform: rotate(45deg) scaleY(1);
+      }
+    }
+  }
+}
+// 添加树卡片样式
+.tree-card {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+
+  :deep(.hc-card-body) {
+    flex: 1;
+    height: 0;
+    display: flex;
+    flex-direction: column;
+    padding: 0;
+  }
+}
+
+// 修改滚动容器样式
+.tree-scrollbar {
+  flex: 1;
+  height: 0;
+  margin-top: 12px;
+  
+  :deep(.el-scrollbar__view) {
+    height: 100%;
+  }
+}
+</style>

+ 38 - 0
src/views/data-fill/wbs.vue

@@ -1393,6 +1393,16 @@
                 </el-form-item>
             </el-form>
         </hc-new-dialog>
+        <!-- 跨节点移动 -->
+              
+        <JumpTreeDialog
+            v-model="moveDialogShow"
+            :contract-id="contractId"
+            :class-type="classType"
+            :auth-btn-tab-key="authBtnTabKey"
+           
+            @save="moveSaveClick"
+        />
     </div>
 </template>
 
@@ -1435,6 +1445,7 @@ import { HcDelMsg, NewDelMsg } from 'hc-vue3-ui'
 import HcUpload from './components/HcUpload.vue'
 import { toPdfPage } from '~uti/btn-auth'
 import website from '~src/config'
+import JumpTreeDialog from './components/JumpTreeDialog.vue'
 
 //初始变量
 const router = useRouter()
@@ -1706,6 +1717,13 @@ const setElTreeMenu = (contractType) => {
                 key: 'nodetree',
             })
         }
+        if (HcIsButton('wbs_tree_jump')) {
+            newArr.push({
+                icon: 'drag-move-2',
+                label: '跨节点移动',
+                key: 'jumpTree',
+            })
+        }
     } else if (contractType === 2) {
         if (HcIsButton('wbs_tree_add')) {
             newArr.push({ icon: 'add-circle', label: '新增节点', key: 'add' })
@@ -2028,7 +2046,12 @@ const setTreeMenuDataClick = ({ key, node, data }) => {
         sortNodeModal.value = true
     } else if (key === 'nodetree') {
         divisionClick()
+    } else if (key === 'jumpTree') {
+        console.log('跨节点移动')
+           
+         showMoveClick(node, data)
     }
+        
 }
 
 //获取节点的路径名字
@@ -3660,6 +3683,21 @@ const nodeBaseDataModalSave = async ()=>{
   
     }
 }
+const showMoveClick = async (node, data)=>{
+    await nextTick()
+    console.log(data, 'data')
+    
+      moveDialogShow.value = true
+}
+const moveDialogShow = ref(false)
+/**
+* 关闭移动对话框
+*
+* 当点击保存按钮时,调用此方法关闭移动对话框。
+*/
+const moveSaveClick = ()=>{
+    moveDialogShow.value = false
+}
 </script>
 
 <style lang="scss" scoped>