'use strict'; /** * 标段项目节数据模型 * * @author CaiAoLin * @date 2017/12/1 * @version */ module.exports = app => { class TenderNode extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'tender_node'; } /** * 新增数据 * * @param {Object} data - 新增的数据(可批量) * @param {Number} tenderId - 标段id * @return {Boolean} - 返回新增的结果 */ async add(data, tenderId) { this.transaction = await this.db.beginTransaction(); let result = false; try { if (tenderId <= 0) { throw '标段id错误'; } if (data instanceof Array) { // 数组则为批量插入 if (data.length <= 0) { throw '插入数据为空'; } // 整理数据 const insertData = []; for (const tmp of data) { tmp.template_id = tmp.id; tmp.template_pid = tmp.pid; tmp.tender_id = tenderId; delete tmp.id; delete tmp.pid; insertData.push(tmp); } const operate = await this.transaction.insert(this.tableName, insertData); this.transaction.commit(); result = operate.affectedRows > 0; } else { // 对象则单个插入 } } catch (error) { result = false; } return result; } /** * 根据层级获取数据 * * @param {Number} tenderId - 标段id * @param {Boolean} showAll - 是否显示全部 * @return {Array} - 返回数据 */ async getDataByTenderId(tenderId, showAll = false) { if (tenderId <= 0) { return []; } const showLevel = !showAll ? 2 : -1; this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: tenderId, operate: '=', }); if (showLevel > 0) { this.sqlBuilder.setAndWhere('level', { value: showLevel, operate: '<=', }); } const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); const data = await this.db.query(sql, sqlParam); return data; } /** * 根据节点Id获取数据 * * @param {Number} tenderId - 标段id * @param {Number} nodeId - 项目节/工程量清单节点id * @return {Object} - 返回查询到的节点数据 */ async getDataByNodeId(tenderId, nodeId) { if ((nodeId <= 0) || (tenderId <= 0)) { return undefined; } this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: tenderId, operate: '=', }); this.sqlBuilder.setAndWhere('template_id', { value: nodeId, operate: '=', }); const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); const data = await this.db.queryOne(sql, sqlParam); return data; } /** * select的全部后兄弟节点,Order自增 * * @param {Object} select - 选中的节点 * @return {Array} - 自增后的数据 * @private */ async _updateSelectNextsOrder(select) { this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: select.tender_id, operate: '=', }); this.sqlBuilder.setAndWhere('order', { value: select.order + 1, operate: '>=', }); this.sqlBuilder.setAndWhere('template_pid', { value: select.template_pid, operate: '=', }); this.sqlBuilder.setUpdateData('order', { value: 1, selfOperate: '+', }); // sql = update this.tableName set order = order + 1 where (tender_id = select.tender_id) && (pid = select.pid) && (order >= select.order+1) const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update'); const data = await this.transaction.query(sql, sqlParam); return data; } /** * 从数据库获取标段的最大节点id * @param {Number} tenderId - 标段id * @return {Number} * @private */ async _getMaxNodeId(tenderId) { const sql = 'SELECT Max(??) As max_id FROM ?? Where tender_id = ' + tenderId; const sqlParam = ['template_id', this.tableName]; const queryResult = await this.db.queryOne(sql, sqlParam); return queryResult.max_id; } /** * 根据selectData, data 新增数据 * @param {Number} tenderId - 标段id * @param {Object} selectData - 选中节点的数据 * @param {Object} data - 新增节点的初始数据 * @return {Object} - 新增结果 * @private */ async _addNodeData(tenderId, selectData, data) { if (tenderId <= 0) { return undefined; } if (!data) { data = {}; } const cacheKey = 'tender_node_maxId:' + tenderId; let maxId = parseInt(await this.cache.get(cacheKey)); if (!maxId) { maxId = await this._getMaxNodeId(tenderId); this.cache.set(cacheKey, maxId, 'EX', this.ctx.app.config.cacheTime); } data.tender_id = tenderId; data.template_id = maxId + 1; data.template_pid = selectData.template_pid; data.level = selectData.level; data.order = selectData.order + 1; data.full_path = selectData.full_path.replace(selectData.template_id, data.template_id); const result = await this.transaction.insert(this.tableName, data); this.cache.set(cacheKey, maxId + 1, 'EX', this.ctx.app.config.cacheTime); return result; } /** * tenderId标段中, 在selectId后新增一个节点 * @param {Number} tenderId - 标段id * @param {Number} selectId - 选中节点id * @param {Object} data - 新增节点初始化数据 * @return {Array} 新增后的数据,其他被修改的数据 */ async addNode(tenderId, selectId, data) { if ((tenderId <= 0) || (selectId <= 0)) { return []; } const selectData = await this.getDataByNodeId(tenderId, selectId); this.transaction = await this.db.beginTransaction(); if (selectData) { try { // 选中节点的所有后兄弟节点,order+1 await this._updateSelectNextsOrder(selectData); // 数据库创建新增节点数据 await this._addNodeData(tenderId, selectData, data); await this.transaction.commit(); } catch (err) { await this.transaction.rollback(); throw err; } // 查询应返回的结果 this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: selectData.tender_id, operate: '=', }); this.sqlBuilder.setAndWhere('template_pid', { value: selectData.template_pid, operate: '=', }); this.sqlBuilder.setAndWhere('order', { value: selectData.order, operate: '>', }); const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); const resultData = this.db.query(sql, sqlParam); return resultData; } throw '新增节点数据错误'; } } return TenderNode; };