duy пре 2 година
родитељ
комит
148c341540
2 измењених фајлова са 248 додато и 12 уклоњено
  1. 244 10
      src/views/data-fill/components/HcTreeDataV2.vue
  2. 4 2
      src/views/data-fill/wbs.vue

+ 244 - 10
src/views/data-fill/components/HcTreeDataV2.vue

@@ -1,11 +1,67 @@
 <template>
     <el-tree-v2
-        ref="ElTreeRef" :class="[ui]" :data="datas" :props="ElTreeProps"
-        class="hc-tree-node" :filter-method="filterMethod" :height="treeHeight"></el-tree-v2>
+        ref="ElTreeRef" 
+        :class="[ui,submitCounts?'tree-line1':'']"
+        :data="datas" 
+        :props="ElTreeProps"
+        class="hc-tree-node tree-line el-radio-group"
+        :filter-method="filterMethod" 
+        :height="treeHeight"
+        @node-click="ElTreeClick"
+        accordion
+        highlight-current
+        :default-expand-all="false"
+        node-key="primaryKeyId"
+     
+        @node-contextmenu="ElTreeLabelContextMenu"
+        >
+            <template #default="{ node, data }">
+                <div :id="`${idPrefix}${data['primaryKeyId']}`" class="data-custom-tree-node">
+                    <!--树组件,节点名称-->
+                    <div :class="node.level === 1?'level-name':''" class="label">
+                        <span
+                            v-if="(data['type'] > 0 && data['majorDataType'] > 0) || (data['type'] > 0 && data['majorDataType'] <= 0)"
+                            class="hc-tree-node-type">{{
+                                getTreeNodeType(data['type'], data['majorDataType'])
+                            }}</span>
+                        <span
+                            v-if="isColor"
+                            :class="data?.colorStatus === 2?'text-blue':data?.colorStatus === 3?'text-orange':data?.colorStatus === 4?'text-green':''">{{
+                                node.label
+                            }}</span>
+                        <span v-else>{{ node.label }}</span>
+                    </div>
+                    <div v-if="isSubmitCounts" class="text-blue submit-counts">【{{ data.submitCounts ?? 0 }}】</div>
+                    <!--树组件,操作菜单-->
+                    <div v-if="node.level !== 1 && menusData.length > 0" :class="node.showTreeMenu?'show':''"
+                        class="menu-icon1" @click.stop>
+                        <div class="cu-tree-node-popover-menu-icon"
+                            @click.prevent.stop="ElTreeLabelContextMenu($event,data,node)">
+                            <HcIcon name="apps" ui="text-2xl"/>
+                        </div>
+                    </div>
+                    <!--树组件,操作菜单 END-->
+                </div>
+            </template>
+        </el-tree-v2>
+         <!--右键菜单-->
+             <!--右键菜单-->
+    <!-- <HcContextMenu v-if="menusData.length > 0" ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect">
+        <template #mark="{item}">
+            <HcIcon :fill="treeRefData?.isFirst" :name="item.icon" class="menu-item-icon"/>
+            <span class="menu-item-name">{{ treeRefData?.isFirst ? '取消标记为首件' : '标记为首件' }}</span>
+        </template>
+        <template #sort="{item}">
+            <HcIcon :line="false" :name="item.icon" class="menu-item-icon"/>
+            <span class="menu-item-name">{{ item.label }}</span>
+        </template>
+    </HcContextMenu> -->
+
 </template>
 
 <script setup>
 import {ref, watch, nextTick} from "vue";
+import {getTreeNodeType} from '~uti/utils';
 //参数
 const props = defineProps({
     ui: {
@@ -28,6 +84,22 @@ const props = defineProps({
         type: String,
         default: ''
     },
+    ElTreeLoadNode: {
+        type: Boolean,
+        default: true
+    },
+    idPrefix: {
+        type: String,
+        default: 'tree-data-'
+    },
+    isColor: {
+        type: Boolean,
+        default: false
+    },
+    isAutoKeys: {
+        type: Boolean,
+        default: true
+    },
 })
 
 //变量
@@ -41,44 +113,206 @@ const treeHeight = ref(0)
 
 const isSubmitCounts = ref(props.submitCounts);
 const searchInfo = ref(props.searchTreeVal)
+const idPrefix = ref(props.idPrefix);
+const menusData = ref(props.menus)
+const isAutoKeys = ref(props.isAutoKeys)
+const treeRefData = ref(null)
+
 
 //监听
 watch(() => [
     props.height,
     props.submitCounts,
     props.searchTreeVal,
-], ([height, submitCounts, searchTreeVal]) => {
+    props.datas,
+    props.ElTreeLoadNode,
+    props.idPrefix,
+    props.menus,
+    props.isAutoKeys,
+], ([height, submitCounts, searchTreeVal,UserIdPrefix,menus,AutoKeys]) => {
     console.log('height', height)
     treeHeight.value = height
     isSubmitCounts.value = submitCounts
     searchInfo.value = searchTreeVal
+    idPrefix.value = UserIdPrefix
+    menusData.value = menus
+    isAutoKeys.value = AutoKeys
 })
 
+watch(searchInfo, (val) => {
+        if (val) {
+            nextTick(() => {
+              
+                ElTreeRef?.value.filter(val)
+            })
+
+        } else {
+            emit('changeSearch')
+        }
+
+    },
+
+    {immediate: true}
+)
 //事件
 const emit = defineEmits(['menuTap', 'nodeTap', 'changeSearch', 'changetreelaod'])
 
+//节点被点击
+//处理自动展开的节点KEY
+const getNodeExpandKeys = async (node, newKeys) => {
+    const parent = node?.parent ?? []
+    const primaryKeyId = node?.data?.primaryKeyId ?? ''
+    if (primaryKeyId) {
+        newKeys.push(primaryKeyId)
+        await getNodeExpandKeys(parent, newKeys)
+    }
+}
 //节点被点击
 const ElTreeClick = async (data, node) => {
-    console.log('node', node)
-    console.log('data', data)
+    if (isAutoKeys.value) {
+        let autoKeysArr = []
+        await getNodeExpandKeys(node, autoKeysArr)
+        const autoKeys = autoKeysArr.reverse()
+        emit('nodeTap', {node, data, keys: autoKeys})
+    } else {
+        emit('nodeTap', {node, data, keys: []})
+    }
+}
+const getReturnNode = (node, _array, value) => {
+    let isPass = node && node.title && node.title.indexOf(value) !== -1;
+ 
+    isPass ? _array.push(isPass) : '';
+    if (!isPass && node.level != 1 && node.parent) {
+        getReturnNode(node.parent, _array, value);
+    }
 }
-
 //筛选树节点
 const filterMethod = (query, node) => {
-    console.log('query',query)
-    return node.label?.includes(query)
+    if (!query) {
+        return true;
+    }
+    let level = node.title;
+    let _array = [];//这里使用数组存储 只是为了存储值。
+    getReturnNode(node, _array, query);
+    let result = false;
+    _array.forEach((item) => {
+        result = result || item;
+    });
+    setTimeout(() => {
+        emit('changetreelaod', false)
+    }, 1000)
+    return result;
+ 
+}
+//鼠标右键事件
+const contextMenuRef = ref(null)
+const ElTreeLabelContextMenu = (e, data, node) => {
+    const rows = menusData.value || [];
+    if (node.level !== 1 && rows.length > 0) {
+        e.preventDefault();
+        treeRefNode.value = node;
+        treeRefData.value = data;
+        //展开菜单
+        contextMenuRef.value?.showMenu(e)
+    }
+}
+//鼠标右键菜单被点击
+const handleMenuSelect = async ({key}) => {
+    const node = treeRefNode.value;
+    const data = treeRefData.value;
+    //如果为标记菜单
+    if (key === 'mark' && menuMark.value) {
+        if (data.isFirst === true) {
+            emit('menuTap', {key: 'cancel_mark', node, data})
+        } else {
+            emit('menuTap', {key: 'mark', node, data})
+        }
+    } else {
+        // emit('menuTap', {key, node, data})
+        if (isAutoKeys.value) {
+            let autoKeysArr = []
+            await getNodeExpandKeys(node, autoKeysArr)
+            const autoKeys = autoKeysArr.reverse()
+            emit('menuTap', {key, node, data, keys: autoKeys})
+        }
+    }
+}
+//设置树菜单的标记数据
+const setElTreeMenuMark = (keys, isFirst) => {
+    keys.forEach(item => {
+        //根据 data 或者 key 拿到 Tree 组件中的 node
+        let node = ElTreeRef.value.getNode(item)
+        if (!!node) node.data.isFirst = isFirst;
+    })
+}
+//设置树菜单的标记数据
+const removeElTreeNode = (key) => {
+    //根据 data 或者 key 拿到 Tree 组件中的 node
+    let node = ElTreeRef.value.getNode(key)
+    //删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性
+    ElTreeRef.value.remove(node)
 }
-
 // 暴露出去
 defineExpose({
-
+    setElTreeMenuMark,
+    removeElTreeNode,
+    filterMethod
 })
 </script>
 
 <style lang="scss" scoped>
 @import "../../../styles/app/tree.scss";
+.el-radio-group {
+    width: 100% !important;
+    display: inline-grid;
+}
+.data-custom-tree-node {
+    flex: 1;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    .label {
+        flex: 1;
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+    }
+    .submit-counts {
+        position: unset;
+        font-size: 14px;
+    }
+    .menu-icon1 {
+        position: unset;
+        vertical-align: bottom;
+        display: inline-block;
+        pointer-events: none;
+        transition: opacity 0.2s;
+        opacity: 0;
+        right: 0;
+        background: rgba(255, 255, 255, 0.25);
+        border-radius: 2px;
+        .cu-tree-node-popover-menu-icon {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+        }
+    }
+    &:hover {
+        .menu-icon1 {
+            opacity: 1;
+            pointer-events: all;
+            cursor: context-menu;
+        }
+    }
+    .menu-icon1.show {
+        opacity: 1;
+        pointer-events: all;
+        cursor: context-menu;
+    }
+}
 </style>
 <style lang="scss">
+
 .el-tree.hc-tree-node .el-tree-node {
     white-space: nowrap;
     overflow: hidden;

+ 4 - 2
src/views/data-fill/wbs.vue

@@ -134,6 +134,7 @@
                             :menus="ElTreeMenu"
                             :searchTreeVal="searchTreeVal"
                             :submitCounts="true"
+                            :ElTreeLoadNode="searchElTreeLoadNode"
                             isColor
                             @changeSearch="changeisSearch"
                             @changetreelaod="changetreelaod"
@@ -909,8 +910,9 @@ const searchTreeClick = async () => {
     //  isSearchTree.value=true
     //treeLoading.value = true
     if (searchElTreeLoadNode.value === true) {
-        //treeLoading.value = true
-        window?.$message?.warning('请加载完再次点击搜索')
+        treeLoading.value = true
+        window?.$message?.warning('请加载完数据再次进行搜索')
+        searchTreeVal.value=''
     } else {
         isSearchTree.value = true
     }