'use strict'; /** * 指标节点业务类 * * @author Mai * @date 2018/4/19 * @version */ module.exports = app => { const paramConst = app.paramConst; const nodeConst = app.nodeConst; class TemplateNode extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局context * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'template_node'; } /** * 加载默认节点参数 * @param {Array} params - 参数数组 * @param {Array} defaultParams - 默认参数数组 * @param {Number} nodeId - 指标节点Id * @param {Number} tempalteId - 指标模板Id * @private */ _loadDefaultParam(params, defaultParams, nodeId, templateId = 1) { const newParams = JSON.parse(JSON.stringify(defaultParams)); for (const p of newParams) { p.node_id = nodeId; p.template_id = templateId; params.push(p); } } /** * 过滤指标节点的参数(含节点参数初始化) * @param {Array} params - 全部参数数组 * @param {Number} nodeId - 指标节点Id * @private */ _filterNodeParams(params, nodeId) { let nodeParams = params.filter(function (p) { return p.node_id === nodeId; }); if (nodeParams.length > 0) { return nodeParams; } else { this._loadDefaultParam(params, paramConst.defaultNodeParams, nodeId); return params.filter(function (p) { return p.node_id === nodeId; }); } } /** * 从计算规则中解析出指标参数 * @param {String} rule - 指标规则 * @param {Number} nodeId - 指标节点id * @param {Array} params - 参数列表 * @param {Number} templateId - 解析至的模板Id * @returns {*[]} * @private */ _parseParam(rule, nodeId, params, templateId = 1) { if (rule === '') { return ['', '']; } const self = this; const ruleParams = this.ctx.helper.splitByOperator(rule); const codeParams = []; const parseParams = []; const nodeParams = this._filterNodeParams(params, nodeId); const addParam = function (paramName) { if (paramName === '') { return ''; } let param = self.ctx.helper.findObj(paramConst.defaultGlobalParams, 'name', paramName); if (!param) { param = self.ctx.helper.findObj(nodeParams, 'name', paramName); } if (!param) { const newParam = { template_id: templateId, node_id: nodeId, param_id: nodeParams.length + 1, code: paramConst.paramCodeArr[nodeParams.length], name: paramName, match_type: paramConst.matchType.non_match, }; nodeParams.push(newParam); params.push(newParam); return newParam.code; } else { return param.code; } }; if (ruleParams.length > 1) { for (const i in ruleParams) { if (!this.ctx.helper.isOperator(ruleParams[i])) { const paramCode = addParam(ruleParams[i]); codeParams.push(paramCode); parseParams.push(paramCode + '(' + ruleParams[i] + ')'); } else { codeParams.push(ruleParams[i]); parseParams.push(ruleParams[i]); } } return [codeParams.join(''), parseParams.join('')]; } else { const paramCode = addParam(rule); return [paramCode, paramCode + '(' + rule + ')']; } } /** * 查找父节点(根据编号),忽略大小写 * e.g. z1(z), z1-e(z1), z1-e-a(z1-e) * @param code * @param nodes * @returns {*} * @private */ _findParentId(code, nodes) { if (nodes.length === 0) { return -1; } const codeList = code.split('-'); if (codeList.length > 1) { codeList.splice(codeList.length - 1); const parentCode = codeList.join('-'); for (const node of nodes) { if (parentCode.toLowerCase() === node.code.toLowerCase()) { return node.node_id; } } } else { for (const node of nodes) { if (code.toLowerCase().search(node.code.toLowerCase()) === 0) { return node.node_id; } } } } /** * 解析一个Excel工作表内的全部 指标节点 和 指标 * @param {Object} excelSheet * @param {Array} nodes - 解析后的指标节点 * @param {Array} indexes - 解析后的指标 * @param {Number} templateId - 解析至的模板Id * @private */ _parseSheetData(excelSheet, nodes, indexes, params, templateId = 1) { for (const row of excelSheet.data) { if (!row[0]) { continue; } if (this.ctx.helper.ValidTemplateNodeCode(row[0])) { if (!this.ctx.helper.findObj(nodes, 'code', row[0])) { const node = { template_id: templateId, node_id: nodes.length + 1, node_pid: this._findParentId(row[0], nodes) || -1, code: row[0], name: row[1], match_type: row[11] && row[11] !== '' ? nodeConst.matchType.code : nodeConst.matchType.name, match_key: row[11] && row[11] !== '' ? row[11] : row[1], }; nodes.push(node); } } else if (this.ctx.helper.ValidTemplateIndexCode(row[0])) { const index = { code: row[0], name: row[1], unit1: row[2], unit2: row[3], node_id: nodes.length, index_id: indexes.length + 1, rule: row[9] ? row[9] : '', template_id: templateId, }; if (row[4] === '√') { index.index_type = 1; } else if (row[5] === '√') { index.index_type = 2; } else if (row[6] === '√') { index.index_type = 3; } else if (row[7] === '√') { index.index_type = 4; } [index.calc_rule, index.parse_rule] = this._parseParam(index.rule, index.node_id, params, templateId); indexes.push(index); } } } /** * 导入Excel数据 * * @param {Array} excelSheets - Excel文件中的全部工作表 * @returns {Promise} */ async importData(excelSheets, templateId = 1) { let result = false; const limit = 30000; const transaction = await this.db.beginTransaction(); try { const nodes = [], indexes = [], params = []; this._loadDefaultParam(params, paramConst.defaultGlobalParams, 0, templateId); for (const sheet of excelSheets) { this._parseSheetData(sheet, nodes, indexes, params, templateId); } if (nodes.length > 0) { // 删除旧数据 await transaction.delete(this.tableName, {template_id: templateId}); // 插入指标节点数据 const nodeResult = await transaction.insert(this.tableName, nodes); if (nodeResult.affectedRows !== nodes.length) { throw '导入指标节点错误'; } // 插入指标数据 await this.ctx.service.templateIndex.importData(indexes, transaction, templateId); // 插入指标参数 await this.ctx.service.templateParam.importData(params, transaction, templateId); } else { throw 'Excel文件中无标准的指标数据'; } await transaction.commit(); result = true; } catch(err) { await transaction.rollback(); console.log(err); throw err; } return result; } /** * 保存指标节点绑定信息 * * @param data * @returns {Promise<*>} */ async updateNodeMatch(data, condition) { try { if (this.ctx.helper.validMatchCode(data.match_key)) { data.match_type = nodeConst.matchType.code; } else { data.match_type = nodeConst.matchType.name; } await this.db.update(this.tableName, data, {where: condition}); } catch (err) { console.log(err); } return await this.getDataByCondition(condition); } } return TemplateNode; };