'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; } /** * 根据 父节点id 和 节点排序order 获取数据 * @param {Number} tenderId - 标段id * @param {Number} pid - 父节点id * @param {Number|Array} order - 排序 * @returns {Object|Array} - 查询结果 */ async getDataByParentAndOrder(tenderId, pid, order) { if ((tenderId <= 0) || (pid <= 0) || (order <= 0)) { return undefined; } this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: tenderId, operate: '=' }); this.sqlBuilder.setAndWhere('template_pid', { value: pid, operate: '=', }); if (order instanceof Array) { this.sqlBuilder.setAndWhere('order', { value: order, operate: 'in' }); } else { this.sqlBuilder.setAndWhere('order', { value: order, operate: '=' }); } const [sql, sqlParam] = this.sqlBuilder.build(this.tableName); let data; if (order instanceof Array) { data = await this.db.query(sql, sqlParam); } else { 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; } else { throw '新增节点数据错误'; } } /** * tenderId标段中, 删除选中节点及其子节点 * @param {Number} tenderId - 标段id * @param {Number} selectId - 选中节点id * @return {Array} - 被删除的数据 */ async deleteNode(tenderId, selectId) { if ((tenderId <= 0) || (selectId <= 0)) { return []; } const selectData = await this.getDataByNodeId(tenderId, selectId); this.transaction = await this.db.beginTransaction(); let resultData = []; if (selectData) { try { // 获取将要被删除的数据 this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: tenderId, operate: '=' }); this.sqlBuilder.setAndWhere('full_path', { value: this.db.escape(selectData.full_path + '%'), operate: 'Like' }); let [sql, sqlParam] = this.sqlBuilder.build(this.tableName); resultData = await this.db.query(sql, sqlParam); // 删除 this.initSqlBuilder(); this.sqlBuilder.setAndWhere('tender_id', { value: tenderId, operate: '=' }); this.sqlBuilder.setAndWhere('full_path', { value: this.db.escape(selectData.full_path + '%'), operate: 'Like' }); [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'delete'); const operate = await this.transaction.query(sql, sqlParam); this.transaction.commit(); } catch(err) { resultData = []; await this.transaction.rollback(); throw err; } return resultData; } else { throw '删除节点数据错误'; } } /** * tenderId标段中, 选中节点selectId上移 * @param {Number} tenderId - 标段id * @param {Number} selectId - 选中节点id * @return {Array} - 发生改变的数据 */ async upMoveNode(tenderId, selectId) { if ((tenderId <= 0) || (selectId <= 0)) { return []; } const selectData = await this.getDataByNodeId(tenderId, selectId); const preData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, selectData.order - 1); this.transaction = await this.db.beginTransaction(); if (selectData && preData) { try { const sData = await this.transaction.update(this.tableName, {id: selectData.id, order: selectData.order - 1}); const pData = await this.transaction.update(this.tableName, {id: preData.id, order: preData.order + 1}); this.transaction.commit(); } catch (err) { await this.transaction.rollback(); throw err; } const resultData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, [selectData.order, preData.order]); return resultData; } else { throw '上移节点数据错误'; } } /** * tenderId标段中, 选中节点selectId下移 * @param {Number} tenderId - 标段id * @param {Number} selectId - 选中节点id * @return {Array} - 发生改变的数据 */ async downMoveNode(tenderId, selectId) { if ((tenderId <= 0) || (selectId <= 0)) { return []; } const selectData = await this.getDataByNodeId(tenderId, selectId); const nextData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, selectData.order + 1); this.transaction = await this.db.beginTransaction(); if (selectData && nextData) { try { const sData = await this.transaction.update(this.tableName, {id: selectData.id, order: selectData.order + 1}); const pData = await this.transaction.update(this.tableName, {id: nextData.id, order: nextData.order - 1}); this.transaction.commit(); } catch (err) { await this.transaction.rollback(); throw err; } const resultData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, [selectData.order, nextData.order]); return resultData; } else { throw '下移节点数据错误'; } } } return TenderNode; };