'use strict'; /** * * * @author Mai * @date * @version */ const itemsPre = 'id_'; class billsTree { /** * 构造函数 */ constructor (ctx, setting) { this.ctx = ctx; // 无索引 this.datas = []; // 以key为索引 this.items = {}; // 以排序为索引 this.nodes = []; // 根节点 this.children = []; // 树设置 this.setting = setting; } /** * 根据id获取树结构节点数据 * @param {Number} id * @returns {Object} */ getItems (id) { return this.items[itemsPre + id]; }; /** * 查找node的parent * @param {Object} node * @returns {Object} */ getParent (node) { return this.getItems(node[this.setting.pid]); }; /** * 查询node的已下载子节点 * @param {Object} node * @returns {Array} */ getChildren (node) { const setting = this.setting; const pid = node ? node[setting.id] : setting.rootId; const children = this.datas.filter(function (x) { return x[setting.pid] === pid; }); children.sort(function (a, b) { return a.order - b.order; }); return children; }; /** * 树结构根据显示排序 */ sortTreeNode (isResort) { const self = this; const addSortNodes = function (nodes) { if (!nodes) { return } for (let i = 0; i < nodes.length; i++) { self.nodes.push(nodes[i]); nodes[i].index = self.nodes.length - 1; if (!isResort) { nodes[i].children = self.getChildren(nodes[i]); } else { nodes[i].children.sort(function (a, b) { return a.order - b.order; }) } addSortNodes(nodes[i].children); } }; this.nodes = []; if (!isResort) { this.children = this.getChildren(); } else { this.children.sort(function (a, b) { return a.order - b.order; }) } addSortNodes(this.children); } /** * 加载数据(初始化), 并给数据添加部分树结构必须数据 * @param datas */ loadDatas (datas) { // 清空旧数据 this.items = {}; this.nodes = []; this.datas = []; this.children = []; // 加载全部数据 datas.sort(function (a, b) { return a.level - b.level; }); for (const data of datas) { const keyName = itemsPre + data[this.setting.id]; if (!this.items[keyName]) { const item = JSON.parse(JSON.stringify(data)); item.children = []; item.expanded = true; item.visible = true; this.items[keyName] = item; this.datas.push(item); if (item[this.setting.pid] === this.setting.rootId) { this.children.push(item); } else { const parent = this.getParent(item); if (parent) { parent.children.push(item); } } } } this.children.sort(function (a, b) { return a.order - b.order; }); this.sortTreeNode(true); } /** * 递归方式 查询node的已下载的全部后代 (兼容full_path不存在的情况) * @param node * @returns {*} * @private */ _recursiveGetPosterity (node) { let posterity = node.children; for (const c of node.children) { posterity = posterity.concat(this._recursiveGetPosterity(c)); } return posterity; }; /** * 查询node的已下载的全部后代 * @param {Object} node * @returns {Array} */ getPosterity (node) { if (node.full_path !== '') { const reg = new RegExp('^' + node.full_path + '-'); return this.datas.filter(function (x) { return reg.test(x.full_path); }); } else { return this._recursiveGetPosterity(node); } }; /** * 检查节点是否是最底层项目节 * @param node * @returns {boolean} */ isLeafXmj(node) { if (node.b_code && node.b_code !== '') { return false; } for (const child of node.children) { if (!child.b_code || child.b_code === '') { return false; } } return true; } /** * 查询最底层项目节(本身或父项) * @param {Object} node - 查询节点 * @returns {Object} */ getLeafXmjParent(node) { let parent = node; while (parent) { if (this.isLeafXmj(parent)) { return parent; } else { parent = this.getParent(parent); } } return null; } _mapTreeNode () { let map = {}, maxLevel = 0; for (const node of this.nodes) { let levelArr = map[node.level]; if (!levelArr) { levelArr = []; map[node.level] = levelArr; } if (node.level > maxLevel) { maxLevel = node.level; } levelArr.push(node); } return [maxLevel, map]; } _calculateNode (node) { const self = this; if (node.children && node.children.length > 0) { const gather = node.children.reduce(function (rst, x) { const result = {}; for (const cf of self.setting.calcFields) { result[cf] = self.ctx.helper.add(rst[cf], x[cf]); } return result; }); // 汇总子项 for (const cf of this.setting.calcFields) { if (gather[cf]) { node[cf] = gather[cf]; } else { node[cf] = null; } } } // 自身运算 if (this.setting.calc) { this.setting.calc(node); } } calculateAll() { const [maxLevel, levelMap] = this._mapTreeNode(); for (let i = maxLevel; i >= 0; i--) { const levelNodes = levelMap[i]; if (levelNodes && levelNodes.length > 0) { for (const node of levelNodes) { this._calculateNode(node); } } } } } class pos { /** * 构造函数 * @param {id|Number, masterId|Number} setting */ constructor (setting) { // 无索引 this.datas = []; // 以key为索引 this.items = {}; // 以分类id为索引的有序 this.ledgerPos = {}; // pos设置 this.setting = setting; } /** * 加载部位明细数据 * @param datas */ loadDatas(datas) { this.datas = datas; this.items = {}; this.ledgerPos = {}; for (const data of this.datas) { const key = itemsPre + data[this.setting.id]; this.items[key] = data; const masterKey = itemsPre + data[this.setting.ledgerId]; if (!this.ledgerPos[masterKey]) { this.ledgerPos[masterKey] = []; } this.ledgerPos[masterKey].push(data); } for (const prop in this.ledgerPos) { this.resortLedgerPos(this.ledgerPos[prop]); } } getLedgerPos(mid) { return this.ledgerPos[itemsPre + mid]; } resortLedgerPos(ledgerPos) { if (ledgerPos instanceof Array) { ledgerPos.sort(function (a, b) { return a.porder - b.porder; }) } } /** * 计算全部 */ calculateAll() { if (!this.setting.calc) { return; } for (const pos of this.datas) { this.setting.calc(pos); } } } module.exports = { billsTree, pos, };