20260901173242
This commit is contained in:
1 parent
3bbcafc5be
commit
53aba8b956
21 files changed
+1595
-704
No files matched your search
@@ -53,3 +53,138 @@ export function sortTree(tree, xhKey = 'b_xh', idKey = 'b_id') {
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
/**
|
||||
* 在树中递归查找指定 id 的节点。
|
||||
* @param {Array} nodes 树形数组
|
||||
* @param {string|number} id 目标节点 ID
|
||||
* @param {string} idKey 节点 ID 字段名,默认 "b_id"
|
||||
* @param {string} childrenKey 子节点字段名,默认 "children"
|
||||
*/
|
||||
export function findTreeNode(nodes, id, idKey = 'b_id', childrenKey = 'children') {
|
||||
for (const node of nodes) {
|
||||
if (String(node[idKey]) === String(id)) return node
|
||||
if (node[childrenKey]) {
|
||||
const found = findTreeNode(node[childrenKey], id, idKey, childrenKey)
|
||||
if (found) return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归收集所有节点 key。
|
||||
* @param {Array} nodes 树形数组
|
||||
* @param {string} idKey 节点 ID 字段名,默认 "b_id"
|
||||
* @param {string} childrenKey 子节点字段名,默认 "children"
|
||||
*/
|
||||
export function collectAllKeys(nodes, idKey = 'b_id', childrenKey = 'children') {
|
||||
const keys = []
|
||||
const walk = (list) => {
|
||||
for (const node of list) {
|
||||
keys.push(String(node[idKey]))
|
||||
if (node[childrenKey]) walk(node[childrenKey])
|
||||
}
|
||||
}
|
||||
walk(nodes)
|
||||
return keys
|
||||
}
|
||||
|
||||
/**
|
||||
* 从根到目标节点的祖先路径(不包含目标节点自身)。
|
||||
* @param {Array} nodes 树形数组
|
||||
* @param {string|number} targetId 目标节点 ID
|
||||
* @param {string} idKey 节点 ID 字段名,默认 "b_id"
|
||||
* @param {string} childrenKey 子节点字段名,默认 "children"
|
||||
*/
|
||||
export function expandAncestors(nodes, targetId, idKey = 'b_id', childrenKey = 'children') {
|
||||
const keys = []
|
||||
const walk = (list, ancestors) => {
|
||||
for (const node of list) {
|
||||
const key = String(node[idKey])
|
||||
if (key === String(targetId)) {
|
||||
keys.push(...ancestors)
|
||||
return true
|
||||
}
|
||||
if (node[childrenKey] && walk(node[childrenKey], [...ancestors, key])) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
walk(nodes, [])
|
||||
return keys
|
||||
}
|
||||
|
||||
/**
|
||||
* 按关键字匹配树节点名称/编码,命中节点保留其子树。
|
||||
* @param {Array} nodes 树形数组
|
||||
* @param {string} keyword 搜索关键字
|
||||
* @param {string[]} textKeys 搜索匹配的字段名列表,默认 ["b_name", "b_code"]
|
||||
* @param {string} childrenKey 子节点字段名,默认 "children"
|
||||
*/
|
||||
export function filterTreeByText(
|
||||
nodes,
|
||||
keyword,
|
||||
textKeys = ['b_name', 'b_code'],
|
||||
childrenKey = 'children',
|
||||
) {
|
||||
const kw = String(keyword || '').trim().toLowerCase()
|
||||
if (!kw) return nodes
|
||||
const result = []
|
||||
for (const node of nodes) {
|
||||
const hit = textKeys.some((k) => String(node[k] || '').toLowerCase().includes(kw))
|
||||
const children = node[childrenKey] ? filterTreeByText(node[childrenKey], keyword, textKeys, childrenKey) : undefined
|
||||
if (hit || children?.length) {
|
||||
result.push({ ...node, [childrenKey]: children })
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 将节点插入到树中(按 parentIdKey 匹配父节点,顶级节点 parentIdKey 为 null/undefined 时插入根层)。
|
||||
* 就地修改树,不返回新数组。
|
||||
* @param {Array} nodes 树形数组(就地修改)
|
||||
* @param {Object} node 待插入节点
|
||||
* @param {Object} [options]
|
||||
* @param {string} [options.parentIdKey="b_parent_id"] 父节点 ID 字段名
|
||||
* @param {string} [options.idKey="b_id"] 节点 ID 字段名
|
||||
* @param {string} [options.childrenKey="children"] 子节点字段名
|
||||
* @param {Function} [options.sort] 可选排序函数,插入所在层后调用(如 sortTree)
|
||||
*/
|
||||
export function insertTreeNode(
|
||||
nodes,
|
||||
node,
|
||||
{ parentIdKey = 'b_parent_id', idKey = 'b_id', childrenKey = 'children', sort } = {},
|
||||
) {
|
||||
if (node[parentIdKey] == null) {
|
||||
nodes.push(node)
|
||||
if (sort) sort(nodes)
|
||||
return
|
||||
}
|
||||
for (const n of nodes) {
|
||||
if (String(n[idKey]) === String(node[parentIdKey])) {
|
||||
n[childrenKey] = n[childrenKey] || []
|
||||
n[childrenKey].push(node)
|
||||
if (sort) sort(n[childrenKey])
|
||||
return
|
||||
}
|
||||
if (n[childrenKey]) insertTreeNode(n[childrenKey], node, { parentIdKey, idKey, childrenKey, sort })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从树中移除指定 id 的节点(就地修改)。
|
||||
* @param {Array} nodes 树形数组(就地修改)
|
||||
* @param {string|number} id 目标节点 ID
|
||||
* @param {string} idKey 节点 ID 字段名,默认 "b_id"
|
||||
* @param {string} childrenKey 子节点字段名,默认 "children"
|
||||
*/
|
||||
export function removeTreeNode(nodes, id, idKey = 'b_id', childrenKey = 'children') {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
if (String(nodes[i][idKey]) === String(id)) {
|
||||
nodes.splice(i, 1)
|
||||
return
|
||||
}
|
||||
if (nodes[i][childrenKey]) removeTreeNode(nodes[i][childrenKey], id, idKey, childrenKey)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user