'use strict'; /** * 指标节点业务类 * * @author Mai * @date 2018/4/19 * @version */ const paramCode = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'ag', 'ah', 'ai', 'aj', 'ak', 'al', 'am', 'an', 'ao', 'ap', 'aq', 'ar', 'as', 'at', 'au', 'av', 'aw', 'ax', 'ay', 'az']; const paramConst = require('../const/template_param'); const nodeConst = require('../const/template_node'); module.exports = app => { 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 * @private */ _loadDefaultParam(params, defaultParams, nodeId) { const newParams = JSON.parse(JSON.stringify(defaultParams)); for (const p of newParams) { p.node_id = nodeId; 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 - 参数列表 * @returns {*[]} * @private */ _parseParam(rule, nodeId, params) { if (rule === '') { return; } const self = this; const ruleParams = rule.split('/'); 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: 1, node_id: nodeId, param_id: nodeParams.length + 1, code: paramCode[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) { const paramName1 = ruleParams[0]; const paramCode1 = addParam(paramName1); const paramName2 = ruleParams.slice(1, ruleParams.length).join('/'); const paramCode2 = addParam(paramName2); return [paramCode1 + '/' + paramCode2, paramCode1 + '(' + paramName1 + ')' + '/' + paramCode2 + '(' + paramName2 + ')']; } 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 - 解析后的指标 * @private */ _parseSheetData(excelSheet, nodes, indexes, params) { 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: 1, node_id: nodes.length + 1, node_pid: this._findParentId(row[0], nodes) || -1, code: row[0], name: 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] }; 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); indexes.push(index); } } } /** * 导入Excel数据 * * @param {Array} excelSheets - Excel文件中的全部工作表 * @returns {Promise} */ async importData(excelSheets) { let result = false; const limit = 30000; const transaction = await this.db.beginTransaction(); try { const nodes = [], indexes = [], params = []; this._loadDefaultParam(params, paramConst.defaultGlobalParams, 0); console.log(params); for (const sheet of excelSheets) { this._parseSheetData(sheet, nodes, indexes, params); } if (nodes.length > 0) { await transaction.delete(this.tableName, {template_id: 1}); const insertResult = await transaction.insert(this.tableName, nodes); if (insertResult.affectedRows !== nodes.length) { throw '导入指标节点错误'; } await this.ctx.service.templateIndex.importData(indexes, transaction); await this.ctx.service.templateParam.importData(params, transaction); } 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; };