|
@@ -1,7 +1,8 @@
|
|
|
<template>
|
|
|
- <ElTree class="hc-tree-node" ref="ElTreeRef" :props="ElTreeProps" :load="ElTreeLoadNode" node-key="primaryKeyId" lazy highlight-current accordion @node-click="ElTreeClick" @node-contextmenu="ElTreeLabelContextMenu">
|
|
|
+ <ElTree class="hc-tree-node" ref="ElTreeRef" :props="ElTreeProps" :load="ElTreeLoadNode" lazy highlight-current accordion node-key="primaryKeyId"
|
|
|
+ :default-expanded-keys="defaultExpandedCids" @node-click="ElTreeClick" @node-contextmenu="ElTreeLabelContextMenu">
|
|
|
<template #default="{ node, data }">
|
|
|
- <div class="data-custom-tree-node" :id="'wbs-tree-' + data['primaryKeyId']">
|
|
|
+ <div class="data-custom-tree-node" :id="`wbs-tree-${data['primaryKeyId']}`">
|
|
|
<!--树组件,节点名称-->
|
|
|
<div class="label" :class="node.level === 1?'level-name':''">
|
|
|
<span :class="data?.colorStatus === 2?'text-blue':data?.colorStatus === 3?'text-orange':data?.colorStatus === 4?'text-green':''">{{ node.label }}</span>
|
|
@@ -18,29 +19,23 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</ElTree>
|
|
|
- <n-dropdown placement="bottom" trigger="manual" :x="x" :y="y" size="huge" :options="menusData" :show="showDropdown" @clickoutside="onClickoutside" @select="handleMenuSelect" v-if="menusData.length > 0"/>
|
|
|
+ <n-dropdown placement="bottom" trigger="manual" :x="menusX" :y="menusY" size="huge" :options="menusData" :show="showDropdown" @clickoutside="onClickoutside" @select="handleMenuSelect" v-if="menusData.length > 0"/>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import {ref,nextTick,watch} from "vue";
|
|
|
import {hIconJs} from "~src/plugins/renderele";
|
|
|
import dataFillQuery from '~api/data-fill/query';
|
|
|
-import { NDropdown } from 'naive-ui';
|
|
|
+import {utilsArray} from "vue-utils-plus"
|
|
|
+import {NDropdown} from 'naive-ui';
|
|
|
|
|
|
+const { isItem } = utilsArray()
|
|
|
//参数
|
|
|
const props = defineProps({
|
|
|
menus: {
|
|
|
type: Array,
|
|
|
default: () => ([])
|
|
|
},
|
|
|
- props: {
|
|
|
- type: Object,
|
|
|
- default: () => ({
|
|
|
- label: 'label',
|
|
|
- children: 'children',
|
|
|
- isLeaf: 'leaf'
|
|
|
- })
|
|
|
- },
|
|
|
params: {
|
|
|
type: Object,
|
|
|
default: () => ({})
|
|
@@ -53,6 +48,10 @@ const props = defineProps({
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
+ isAutoKeys: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
})
|
|
|
|
|
|
//变量
|
|
@@ -61,80 +60,96 @@ const showDropdown = ref(false)
|
|
|
const treeRefNode = ref(null)
|
|
|
const treeRefData = ref(null)
|
|
|
const ElTreeProps = ref({
|
|
|
- label: props.props?.label || 'title',
|
|
|
- children: props.props?.children || 'children',
|
|
|
- isLeaf: props.props?.isLeaf || 'leaf'
|
|
|
+ label: 'title',
|
|
|
+ children: 'children',
|
|
|
+ isLeaf: 'notExsitChild'
|
|
|
})
|
|
|
const menusData = ref(props.menus)
|
|
|
-const x = ref(0);
|
|
|
-const y = ref(0);
|
|
|
+const menusX = ref(0);
|
|
|
+const menusY = ref(0);
|
|
|
|
|
|
const menuMark = ref(props.isMark)
|
|
|
+const isAutoKeys = ref(props.isAutoKeys)
|
|
|
const TreeExpandKey = ref(props.autoExpandKeys)
|
|
|
|
|
|
//监听
|
|
|
watch(() => [
|
|
|
props.menus,
|
|
|
props.isMark,
|
|
|
+ props.isAutoKeys,
|
|
|
props.autoExpandKeys
|
|
|
-], ([menus,isMark,expandKeys]) => {
|
|
|
+], ([menus, isMark, AutoKeys, expandKeys]) => {
|
|
|
menusData.value = menus
|
|
|
menuMark.value = isMark
|
|
|
+ isAutoKeys.value = AutoKeys
|
|
|
TreeExpandKey.value = expandKeys
|
|
|
- if (expandKeys?.length > 0) {
|
|
|
- setTreeAutoExpandKey()
|
|
|
- }
|
|
|
})
|
|
|
|
|
|
-nextTick().then(() => {
|
|
|
- //1551464734866276744
|
|
|
- //console.log(ElTreeRef.value)
|
|
|
- if (TreeExpandKey.value?.length > 0) {
|
|
|
- setTreeAutoExpandKey()
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-//懒加载tree,自动展开上次记忆的节点
|
|
|
-const setTreeAutoExpandKey = () => {
|
|
|
- const keys = TreeExpandKey.value || []
|
|
|
- let num = 0, numMax = keys.length;
|
|
|
- let timer = setInterval(() => {
|
|
|
- if(num < numMax) {
|
|
|
- document.getElementById('wbs-tree-' + keys[num])?.click()
|
|
|
- num++;
|
|
|
- } else {
|
|
|
- clearInterval(timer);
|
|
|
- }
|
|
|
- }, 800);
|
|
|
-}
|
|
|
-
|
|
|
-//事件
|
|
|
-const emit = defineEmits(['menuTap','node-click','load-click'])
|
|
|
-
|
|
|
//树形结构异步加载数据
|
|
|
-const ElTreeLoadNode = (node, resolve) => {
|
|
|
+const defaultExpandedCids = ref([])
|
|
|
+const ElTreeLoadNode = async (node, resolve) => {
|
|
|
let contractIdRelation = '', parentId = '';
|
|
|
if (node.level !== 0) {
|
|
|
const nodeData = node?.data ?? {};
|
|
|
contractIdRelation = nodeData?.contractIdRelation ?? ''
|
|
|
parentId = contractIdRelation ? nodeData?.primaryKeyId : nodeData?.id
|
|
|
}
|
|
|
- emit('load-click', {node, data: node.data})
|
|
|
//获取数据
|
|
|
- dataFillQuery.queryWbsTreeData({
|
|
|
+ const { data } = await dataFillQuery.queryWbsTreeData({
|
|
|
contractId: props.params?.contractId || '',
|
|
|
contractIdRelation,
|
|
|
parentId
|
|
|
- }).then(res => {
|
|
|
- resolve(res?.data?.data || [])
|
|
|
- }).catch(() => {
|
|
|
- resolve([])
|
|
|
+ })
|
|
|
+ //处理数据
|
|
|
+ let clickKey = '', defaultExpandedArr = [];
|
|
|
+ const keys = TreeExpandKey.value || []
|
|
|
+ const resData = data?.data || []
|
|
|
+ const pKeyId = resData[0]?.primaryKeyId
|
|
|
+ if (keys.length > 0) {
|
|
|
+ //自动展开
|
|
|
+ if (isItem(keys,pKeyId)) {
|
|
|
+ defaultExpandedArr.push(pKeyId)
|
|
|
+ }
|
|
|
+ //最后一个,选中点击
|
|
|
+ let lastKey = keys[keys.length-1];
|
|
|
+ if (pKeyId === lastKey) {
|
|
|
+ clickKey = pKeyId
|
|
|
+ }
|
|
|
+ } else if (node.level === 0) {
|
|
|
+ defaultExpandedArr.push(resData[0]?.primaryKeyId)
|
|
|
+ }
|
|
|
+ //自动展开
|
|
|
+ defaultExpandedCids.value = defaultExpandedArr
|
|
|
+ resolve(resData)
|
|
|
+ //最后一个,执行点击
|
|
|
+ await nextTick(() => {
|
|
|
+ if (clickKey) document.getElementById(`wbs-tree-${pKeyId}`)?.click()
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+//事件
|
|
|
+const emit = defineEmits(['menuTap','nodeTap'])
|
|
|
+
|
|
|
//节点被点击
|
|
|
-const ElTreeClick = (data,node,e) => {
|
|
|
- emit('node-click', {node, data, e})
|
|
|
+const ElTreeClick = async (data,node) => {
|
|
|
+ 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: []})
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//处理自动展开的节点KEY
|
|
|
+const getNodeExpandKeys = async (node, newKeys) => {
|
|
|
+ const parent = node?.parent ?? []
|
|
|
+ const primaryKeyId = node?.data?.primaryKeyId ?? ''
|
|
|
+ if (primaryKeyId) {
|
|
|
+ newKeys.push(primaryKeyId)
|
|
|
+ await getNodeExpandKeys(parent, newKeys)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//鼠标右键事件
|
|
@@ -147,10 +162,10 @@ const ElTreeLabelContextMenu = (e,data,node) => {
|
|
|
if (menuMark.value) {
|
|
|
setMenuMarkVal(rows,data)
|
|
|
}
|
|
|
- nextTick().then(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ menusX.value = e.clientX;
|
|
|
+ menusY.value = e.clientY;
|
|
|
showDropdown.value = true;
|
|
|
- x.value = e.clientX;
|
|
|
- y.value = e.clientY;
|
|
|
});
|
|
|
}
|
|
|
}
|
|
@@ -187,6 +202,7 @@ const onClickoutside = () => {
|
|
|
treeRefData.value = null;
|
|
|
showDropdown.value = false;
|
|
|
}
|
|
|
+
|
|
|
//菜单被点击
|
|
|
const ElTreeMenuClick = (key,node,data) => {
|
|
|
emit('menuTap', {key,node,data})
|