|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <div class="cu-tree-node-container" @mousewheel.prevent="treeNodeMousewheel">
|
|
|
+ <div class="cu-tree-node-container" v-loading="treeNodeLoading" @mousewheel.prevent="treeNodeMousewheel">
|
|
|
<div class="cu-tree-node-box horizontal collapsable" :id="'tree-node-' + uuid" @mousedown="treeNodeMouseDown" :style="{zoom: zoomRef + '%'}" v-if="!!nodes.label">
|
|
|
<div class="cu-tree-node-view">
|
|
|
<div class="cu-tree-node-label">
|
|
@@ -9,33 +9,23 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <TreeNodeChildren :data="nodes.childNodes" :format="format" :menus="menus" :parentNodes="nodes" :isMark="isMark" :isColor="TreeIsColor"
|
|
|
- @expandClick="expandClick" @nodeClick="nodeLabelClick" @nodeDblClick="nodeLabelDblClick" @menuClick="poverMenuClick"/>
|
|
|
+ <TreeNodeChildren :data="nodes.childNodes" :menus="menus" :parentNodes="nodes" :isMark="menuMark" @expandClick="expandClick" @nodeClick="nodeLabelClick" @nodeDblClick="nodeLabelDblClick" @menuClick="poverMenuClick"/>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import {watch,ref,onMounted} from "vue";
|
|
|
+import {watch,ref,onMounted,nextTick} from "vue";
|
|
|
+import wbsApi from "~api/data-fill/wbs"
|
|
|
import TreeNodeChildren from "./children.vue";
|
|
|
-import {isType,utilsRandom} from "vue-utils-plus"
|
|
|
+import {isType, utilsArray, utilsRandom} from "vue-utils-plus"
|
|
|
//初始变量
|
|
|
-const { isObject } = isType()
|
|
|
-const { getRandom } = utilsRandom()
|
|
|
+const {getObjValue,getArrValue} = isType()
|
|
|
+const {getRandom} = utilsRandom()
|
|
|
+const {isItem} = utilsArray()
|
|
|
+//参数
|
|
|
const props = defineProps({
|
|
|
- data: {
|
|
|
- type: Object,
|
|
|
- default: () => ({})
|
|
|
- },
|
|
|
- format: {
|
|
|
- type: Object,
|
|
|
- default: () => ({
|
|
|
- key: "key",
|
|
|
- label: "label",
|
|
|
- children: "children",
|
|
|
- })
|
|
|
- },
|
|
|
autoExpandKeys: {
|
|
|
type: Array,
|
|
|
default: () => ([])
|
|
@@ -52,67 +42,103 @@ const props = defineProps({
|
|
|
type: Boolean,
|
|
|
default: false
|
|
|
},
|
|
|
- isColor: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
+ projectId: {
|
|
|
+ type: [String,Number],
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ contractId: {
|
|
|
+ type: [String,Number],
|
|
|
+ default: ''
|
|
|
},
|
|
|
})
|
|
|
|
|
|
//初始数据
|
|
|
const uuid = getRandom()
|
|
|
-const datas = ref(props.data)
|
|
|
+const datas = ref({})
|
|
|
const nodes = ref({})
|
|
|
+const menuMark = ref(props.isMark)
|
|
|
+const projectId = ref(props.projectId);
|
|
|
+const contractId = ref(props.contractId);
|
|
|
const TreeExpandKey = ref(props.autoExpandKeys)
|
|
|
-const TreeIsColor = ref(props.isColor)
|
|
|
|
|
|
//监听
|
|
|
watch(() => [
|
|
|
- props.data,
|
|
|
props.autoExpandKeys,
|
|
|
- props.isColor,
|
|
|
-], ([val,expandKeys,isColor]) => {
|
|
|
- TreeIsColor.value = isColor
|
|
|
- if (isDataType(val)) {
|
|
|
- datas.value = val
|
|
|
- setDatasToNodes()
|
|
|
- } else {
|
|
|
- datas.value = {}
|
|
|
- nodes.value = {}
|
|
|
- }
|
|
|
+ props.isMark,
|
|
|
+ props.projectId,
|
|
|
+ props.contractId,
|
|
|
+], ([expandKeys, isMark, UserProjectId, UserContractId]) => {
|
|
|
TreeExpandKey.value = expandKeys
|
|
|
- if (expandKeys?.length > 0) {
|
|
|
- setTreeAutoExpandKey()
|
|
|
- }
|
|
|
+ menuMark.value = isMark
|
|
|
+ projectId.value = UserProjectId
|
|
|
+ contractId.value = UserContractId
|
|
|
})
|
|
|
|
|
|
//渲染完成
|
|
|
onMounted(()=> {
|
|
|
- if (isDataType(props.data)) {
|
|
|
- datas.value = props.data
|
|
|
- setDatasToNodes()
|
|
|
- } else {
|
|
|
- datas.value = {}
|
|
|
- nodes.value = {}
|
|
|
- }
|
|
|
- if (TreeExpandKey.value?.length > 0) {
|
|
|
- setTreeAutoExpandKey()
|
|
|
- }
|
|
|
+ getTreeOneLevel()
|
|
|
})
|
|
|
|
|
|
-//检查数据类型
|
|
|
-const isDataType = (data) => {
|
|
|
- if (isObject(data)) {
|
|
|
- return Object.keys(data).length !== 0;
|
|
|
- } else {
|
|
|
- return false
|
|
|
+//导图结构树节点查询
|
|
|
+const treeNodeLoading = ref(false)
|
|
|
+const getTreeOneLevel = async () => {
|
|
|
+ treeNodeLoading.value = true
|
|
|
+ const data = await queryMappingStructureTree({
|
|
|
+ contractId: contractId.value,
|
|
|
+ contractIdRelation: '',
|
|
|
+ parentId: '0',
|
|
|
+ })
|
|
|
+ //处理数据
|
|
|
+ const res = getObjValue(data[0])
|
|
|
+ //自动展开第二级
|
|
|
+ const keys = TreeExpandKey.value || []
|
|
|
+ if (keys.length > 0) {
|
|
|
+ const children = await queryMappingStructureTree({
|
|
|
+ contractId: contractId.value,
|
|
|
+ contractIdRelation: res?.contractIdRelation,
|
|
|
+ parentId: res?.contractIdRelation ? res?.primaryKeyId: res?.id,
|
|
|
+ })
|
|
|
+ if (children.length > 0) {
|
|
|
+ await setTreeExpandKey(children, res)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ datas.value = res
|
|
|
+ setDatasToNodes()
|
|
|
+ treeNodeLoading.value = false
|
|
|
+}
|
|
|
+
|
|
|
+//设置自动展开
|
|
|
+const setTreeExpandKey = async (arr,res) => {
|
|
|
+ const keys = TreeExpandKey.value || []
|
|
|
+ res.children = []
|
|
|
+ for (const item of arr) {
|
|
|
+ if (isItem(keys, item?.primaryKeyId)) {
|
|
|
+ const children = await queryMappingStructureTree({
|
|
|
+ contractId: contractId.value,
|
|
|
+ contractIdRelation: item?.contractIdRelation,
|
|
|
+ parentId: item?.contractIdRelation ? item?.primaryKeyId: item?.id,
|
|
|
+ })
|
|
|
+ if (children.length > 0) {
|
|
|
+ await setTreeExpandKey(children, item)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ res.children.push(item)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//获取数据
|
|
|
+const queryMappingStructureTree = async (form) => {
|
|
|
+ const {data} = await wbsApi.queryMappingStructureTree({
|
|
|
+ ...form,
|
|
|
+ wbsType: 1
|
|
|
+ })
|
|
|
+ return getArrValue(data?.data)
|
|
|
+}
|
|
|
+
|
|
|
//处理为node节点类型的数据
|
|
|
const setDatasToNodes = () => {
|
|
|
- const {key,label,children} = props.format
|
|
|
const deepData = datas.value
|
|
|
- let childNodes = deepData[children]
|
|
|
+ let childNodes = getArrValue(deepData['children'])
|
|
|
nodes.value = {
|
|
|
childNodes: childNodes,
|
|
|
childrenNodes: [],
|
|
@@ -122,25 +148,11 @@ const setDatasToNodes = () => {
|
|
|
isExpand: deepData['isExpand'] || false,
|
|
|
isLeaf: deepData['isLeaf'] || false,
|
|
|
loading: deepData['loading'] || false,
|
|
|
- key: deepData[key],
|
|
|
- label: deepData[label]
|
|
|
+ key: deepData['primaryKeyId'] || '',
|
|
|
+ label: deepData['title'] || ''
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//懒加载tree,自动展开上次记忆的节点
|
|
|
-const setTreeAutoExpandKey = () => {
|
|
|
- const keys = TreeExpandKey.value || []
|
|
|
- let num = 0, numMax = keys.length;
|
|
|
- let timer = setInterval(() => {
|
|
|
- if(num < numMax) {
|
|
|
- document.getElementById(`node-tree-${keys[num]}`)?.click()
|
|
|
- num++;
|
|
|
- } else {
|
|
|
- clearInterval(timer);
|
|
|
- }
|
|
|
- }, 800);
|
|
|
-}
|
|
|
-
|
|
|
//放大缩小
|
|
|
const zoomRef = ref(100)
|
|
|
const treeNodeMousewheel = (event) => {
|
|
@@ -196,20 +208,73 @@ const treeNodeMouseDown = (event) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//处理自动展开的节点KEY
|
|
|
+const getNodeExpandKeys = async (node, newKeys) => {
|
|
|
+ const parent = node?.parentNodes ?? []
|
|
|
+ const primaryKeyId = node?.data?.primaryKeyId ?? ''
|
|
|
+ if (primaryKeyId) {
|
|
|
+ newKeys.push(primaryKeyId)
|
|
|
+ await getNodeExpandKeys(parent, newKeys)
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
const emit = defineEmits(['expand', 'nodeClick', 'nodeDblClick','menuClick']);
|
|
|
|
|
|
-const expandClick = (item) => {
|
|
|
- emit('expand', item)
|
|
|
+//导图结构展开和收缩被点击
|
|
|
+const expandClick = ({node,data}) => {
|
|
|
+ if (!node.children) {
|
|
|
+ node.expanded = false;
|
|
|
+ }
|
|
|
+ node.isExpand = !node.isExpand;
|
|
|
+ emit('expand', {node,data})
|
|
|
}
|
|
|
+
|
|
|
//鼠标左键单击事件
|
|
|
-const nodeLabelClick = (item) => {
|
|
|
- emit('nodeClick', item)
|
|
|
+const nodeLabelClick = async ({node,data}) => {
|
|
|
+ if (data?.notExsitChild) {
|
|
|
+ await awaitNodeClick(node,data)
|
|
|
+ } else {
|
|
|
+ let ifChildren = !!(node.childNodes && node.childNodes.length > 0);
|
|
|
+ if (ifChildren) {
|
|
|
+ node.expanded = true;
|
|
|
+ node.isExpand = true;
|
|
|
+ node.loading = false
|
|
|
+ await awaitNodeClick(node,data)
|
|
|
+ } else {
|
|
|
+ const children = await queryMappingStructureTree({
|
|
|
+ contractId: contractId.value,
|
|
|
+ contractIdRelation: data?.contractIdRelation,
|
|
|
+ parentId: data?.contractIdRelation ? data?.primaryKeyId: data?.id,
|
|
|
+ })
|
|
|
+ node.childNodes = children
|
|
|
+ await nextTick(async () => {
|
|
|
+ if (children.length > 0) {
|
|
|
+ node.expanded = true;
|
|
|
+ node.isExpand = true;
|
|
|
+ } else {
|
|
|
+ node.expanded = false;
|
|
|
+ node.expanded = false;
|
|
|
+ }
|
|
|
+ node.loading = false
|
|
|
+ await awaitNodeClick(node, data)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//处理数据
|
|
|
+const awaitNodeClick = async (node, data) => {
|
|
|
+ let autoKeysArr = []
|
|
|
+ await getNodeExpandKeys(node, autoKeysArr)
|
|
|
+ const autoKeys = autoKeysArr.reverse()
|
|
|
+ emit('nodeClick', {node, data, keys: autoKeys})
|
|
|
}
|
|
|
+
|
|
|
//双击事件
|
|
|
const nodeLabelDblClick = (item) => {
|
|
|
emit('nodeDblClick', item)
|
|
|
}
|
|
|
+
|
|
|
//菜单被点击
|
|
|
const poverMenuClick = (item) => {
|
|
|
emit('menuClick', item)
|