TestTree.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <template>
  2. <ElTree class="hc-tree-node tree-line"
  3. :class="ui"
  4. ref="ElTreeRef"
  5. :props="ElTreeProps"
  6. :load="ElTreeLoadNode"
  7. lazy
  8. highlight-current
  9. accordion
  10. node-key="primaryKeyId"
  11. :default-expanded-keys="defaultExpandedCids"
  12. @node-click="ElTreeClick"
  13. :indent="0">
  14. <template #default="{ node, data }">
  15. <div class="data-custom-tree-node" :id="`${idPrefix}${data['primaryKeyId']}`">
  16. <div class="label" :class="node.level === 1?'level-name':''">{{ node.label }}</div>
  17. </div>
  18. </template>
  19. </ElTree>
  20. </template>
  21. <script setup>
  22. import {ref,nextTick,watch} from "vue";
  23. import samplingApi from "~api/tentative/material/sampling"
  24. import {isItem,getArrValue} from "vue-utils-plus"
  25. //参数
  26. const props = defineProps({
  27. projectId: {
  28. type: [String,Number],
  29. default: ''
  30. },
  31. contractId: {
  32. type: [String,Number],
  33. default: ''
  34. },
  35. wbsTempId: {
  36. type: [String,Number],
  37. default: ''
  38. },
  39. tenantId: {
  40. type: [String,Number],
  41. default: ''
  42. },
  43. wbsType: {
  44. type: [String,Number],
  45. default: ''
  46. },
  47. autoExpandKeys: {
  48. type: Array,
  49. default: () => ([])
  50. },
  51. idPrefix: {
  52. type: String,
  53. default: 'test-tree-'
  54. },
  55. ui: {
  56. type: String,
  57. default: ''
  58. },
  59. })
  60. //变量
  61. const ElTreeRef = ref(null)
  62. const ElTreeProps = ref({
  63. label: 'title',
  64. children: 'children',
  65. isLeaf: 'hasChildren'
  66. })
  67. const TreeExpandKey = ref(props.autoExpandKeys)
  68. const projectId = ref(props.projectId);
  69. const contractId = ref(props.contractId);
  70. const wbsTempId = ref(props.wbsTempId);
  71. const tenantId = ref(props.tenantId);
  72. const wbsType = ref(props.wbsType);
  73. const idPrefix = ref(props.idPrefix);
  74. //监听
  75. watch(() => [
  76. props.autoExpandKeys,
  77. props.projectId,
  78. props.contractId,
  79. props.wbsTempId,
  80. props.tenantId,
  81. props.idPrefix,
  82. props.wbsType,
  83. ], ([expandKeys, UserProjectId, UserContractId, UserWbsTempId, UserTenantId, UserIdPrefix, wbs_type]) => {
  84. TreeExpandKey.value = expandKeys
  85. projectId.value = UserProjectId
  86. contractId.value = UserContractId
  87. wbsTempId.value = UserWbsTempId
  88. tenantId.value = UserTenantId
  89. idPrefix.value = UserIdPrefix
  90. wbsType.value = wbs_type
  91. })
  92. //事件
  93. const emit = defineEmits(['menuTap','nodeTap', 'nodeLoading'])
  94. //树形结构异步加载数据
  95. const defaultExpandedCids = ref([])
  96. const ElTreeLoadNode = async (node, resolve) => {
  97. let parentId = '0';
  98. if (node.level !== 0) {
  99. parentId = node?.data?.id
  100. }
  101. //获取数据
  102. const {error, code, data} = await samplingApi.queryLazyTree({
  103. wbsId: wbsTempId.value,
  104. tenantId: tenantId.value,
  105. projectId: projectId.value,
  106. parentId,
  107. wbsType: wbsType.value
  108. })
  109. //处理数据
  110. if (!error && code === 200) {
  111. let clickKey = '', defaultExpandedArr = [];
  112. const keys = TreeExpandKey.value || []
  113. const resData = getArrValue(data)
  114. for (let i = 0; i < resData.length; i++) {
  115. resData[i].hasChildren = !resData[i].hasChildren
  116. }
  117. if (keys.length > 0) {
  118. let lastKey = keys[keys.length-1];
  119. for (const item of resData) {
  120. //自动展开
  121. if (isItem(keys,item?.primaryKeyId)) {
  122. defaultExpandedArr.push(item?.primaryKeyId)
  123. }
  124. //最后一个,选中点击
  125. if (item?.primaryKeyId === lastKey) {
  126. clickKey = item?.primaryKeyId
  127. }
  128. }
  129. } else if (node.level === 0) {
  130. defaultExpandedArr.push(resData[0]?.primaryKeyId)
  131. }
  132. //自动展开
  133. defaultExpandedCids.value = defaultExpandedArr
  134. if (node.level === 0) {
  135. emit('nodeLoading')
  136. }
  137. resolve(resData)
  138. //最后一个,执行点击
  139. if (clickKey) {
  140. await nextTick(() => {
  141. document.getElementById(`${idPrefix.value}${clickKey}`)?.click()
  142. })
  143. }
  144. } else {
  145. if (node.level === 0) {
  146. emit('nodeLoading')
  147. }
  148. resolve([])
  149. }
  150. }
  151. //节点被点击
  152. const ElTreeClick = async (data,node) => {
  153. let autoKeysArr = []
  154. await getNodeExpandKeys(node, autoKeysArr)
  155. const autoKeys = autoKeysArr.reverse()
  156. emit('nodeTap', {node, data, keys: autoKeys})
  157. }
  158. //处理自动展开的节点KEY
  159. const getNodeExpandKeys = async (node, newKeys) => {
  160. const parent = node?.parent ?? []
  161. const primaryKeyId = node?.data?.primaryKeyId ?? ''
  162. if (primaryKeyId) {
  163. newKeys.push(primaryKeyId)
  164. await getNodeExpandKeys(parent, newKeys)
  165. }
  166. }
  167. </script>
  168. <style lang="scss" scoped>
  169. @import "../../../../styles/app/tree.scss";
  170. </style>