'use strict'; /** * Created by Tony on 2017/3/14. */ const NODE_ID = 'ledger_id'; const P_ID = 'ledger_pid'; const NEXT_ID = 'NextSiblingID'; const ADHOC_PRE_ID = 'Previous_ID'; const ORDER_ID = 'order'; const CHILDREN_NODE = 'items'; const SUB_ID = 'sub_ids'; const EMPTY_ID_VAL = -1; const TREE_LEVEL = 'treeLevel'; const TOP_BILL_ID = 'topBillID'; const TREE_FLAT_SERIAL_ORDER = 'treeFlatSerialOrder'; function sortOder(item1, item2) { return parseInt(item1[ORDER_ID]) - parseInt(item2[ORDER_ID]); } const tree_Data_Helper = { buildTreeNodeDirectly: function(data, addLevel) { const topArr = []; const rst = []; const nodeCache = {}; const prefix = 'id_'; const private_buildNodeData = function(node, treeLevel, tbID) { const stbID = (tbID === -1) ? node[NODE_ID] : tbID; node[TOP_BILL_ID] = stbID; if (addLevel) { node[TREE_LEVEL] = treeLevel; } if (node[CHILDREN_NODE].length > 0) { node[CHILDREN_NODE].sort(sortOder); for (const subNode of node[CHILDREN_NODE]) { private_buildNodeData(subNode, treeLevel + 1, tbID); } } }; // 1. 给每个节点设置key, 顺便找Top Node for (let i = 0; i < data.length; i++) { nodeCache[prefix + data[i][NODE_ID]] = data[i]; data[i][CHILDREN_NODE] = []; if (parseInt(data[i][P_ID]) === EMPTY_ID_VAL) { topArr.push(data[i]); } } // 2. 通过key,设置父子关系,然后通过order来排序 for (let psi = 0; psi < data.length; psi++) { if (parseInt(data[psi][P_ID]) !== EMPTY_ID_VAL) { const pNode = nodeCache[prefix + data[psi][P_ID]]; if (pNode) { pNode[CHILDREN_NODE].push(data[psi]); } else { console.log('warning: no parent node was found!'); } } } // 3. 开build topArr.sort(sortOder); for (const topNode of topArr) { private_buildNodeData(topNode, 0, -1); } // try to release and return // nodeCache = null; topArr.length = 0; return rst; }, getFlatArray: function(srcArr, destArr, addSerialOrder) { let serialStartOrder = 0; const private_put = function(parentItem) { if (addSerialOrder) { parentItem[TREE_FLAT_SERIAL_ORDER] = serialStartOrder; serialStartOrder++; // 说明:当清单通过树排序后,为了后续的排序方便,有必要加这个序号,并作为指标提供 } destArr.push(parentItem); if (parentItem[CHILDREN_NODE]) { for (const subItem of parentItem[CHILDREN_NODE]) { private_put(subItem); } } } for (const node of srcArr) { private_put(node); } for (const item of destArr) { delete item[CHILDREN_NODE]; } }, }; module.exports = tree_Data_Helper;