treeFunc.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * flat-tree.js
  3. * @author: oldj
  4. * @homepage: https://oldj.net
  5. */
  6. /**
  7. * 将 tree_list 树状对象变成一个平的数组
  8. * @param tree_list {Array} 树状对象
  9. * @param ignore_collapsed {Boolean} 是否忽略折叠起来的对象
  10. * @returns {Array}
  11. */
  12. function flatTree(tree_list, ignore_collapsed = false) {
  13. let arr = []
  14. Array.isArray(tree_list) && tree_list.map((item) => {
  15. if (!item) return
  16. arr.push(item)
  17. if (ignore_collapsed && item.collapsed) return
  18. if (item.children) {
  19. let a2 = flatTree(item.children, ignore_collapsed)
  20. arr = arr.concat(a2)
  21. }
  22. })
  23. return arr
  24. }
  25. const getItemById = (tree, id) => {
  26. return flatTree(tree).find(item => item.id === id)
  27. }
  28. const getItemDetailById = (tree, id, parent = null) => {
  29. let idx = tree.findIndex(i => i.id === id)
  30. if (idx >= 0) {
  31. return {
  32. idx,
  33. item: tree[idx],
  34. parent_list: tree,
  35. parent
  36. }
  37. }
  38. for (let i of tree) {
  39. if (!Array.isArray(i.children)) {
  40. i.children = []
  41. }
  42. let d = getItemDetailById(i.children, id, i)
  43. if (d) {
  44. return d
  45. }
  46. }
  47. return null
  48. }
  49. const removeItemFromTreeById = (tree, id) => {
  50. let idx = tree.findIndex(item => item.id === id)
  51. if (idx >= 0) {
  52. tree.splice(idx, 1)
  53. return tree
  54. }
  55. tree.map(item => removeItemFromTreeById(item.children || [], id))
  56. return tree
  57. }
  58. /**
  59. * 更新 tree
  60. * @param tree
  61. * @param updates
  62. * 包含:source_id, target_id, where_to
  63. * 其中 where_to 的值
  64. */
  65. const updateTree = (tree, updates) => {
  66. let {source_id, target_id, where_to} = updates
  67. if (!source_id || !target_id || source_id === target_id) {
  68. return tree
  69. }
  70. let source_item = getItemById(tree, source_id)
  71. tree = removeItemFromTreeById(tree, source_id)
  72. let {item, parent_list, idx} = getItemDetailById(tree, target_id) || {}
  73. if (!item) {
  74. console.log('no item!')
  75. console.log(source_id, target_id)
  76. return tree
  77. }
  78. if (where_to === 0) {
  79. // in
  80. if (!Array.isArray(item.children)) {
  81. item.children = []
  82. }
  83. item.children.push(source_item)
  84. } else if (where_to === -1) {
  85. // before
  86. parent_list.splice(idx, 0, source_item)
  87. } else {
  88. // after
  89. parent_list.splice(idx + 1, 0, source_item)
  90. }
  91. return tree
  92. }
  93. function getParentList (list, id) {
  94. if (list.findIndex(i => i.id === id) > -1) return list
  95. let fl = flatTree(list)
  96. let found = false
  97. let parent_list = []
  98. fl.map((i) => {
  99. if (found) return
  100. if (i.id === id) {
  101. found = true
  102. parent_list = list
  103. } else if (i.children && i.children.find((i2) => i2.id === id)) {
  104. found = true
  105. parent_list = i.children
  106. }
  107. })
  108. return parent_list
  109. }
  110. function getUpItemWithCollapseState (list, id) {
  111. let f_list = flatTree(list, true)
  112. let idx = f_list.findIndex(i => i.id === id)
  113. return idx > 0 ? f_list[idx - 1] : null
  114. }
  115. function getDownItemWithCollapseState (list, id) {
  116. let f_list = flatTree(list, true)
  117. let idx = f_list.findIndex(i => i.id === id)
  118. return f_list[idx + 1] || null
  119. }
  120. module.exports = {
  121. flatTree,
  122. updateTree,
  123. getItemById,
  124. getItemDetailById,
  125. removeItemFromTreeById,
  126. getUpItemWithCollapseState,
  127. getDownItemWithCollapseState
  128. }