tender_node.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. 'use strict';
  2. /**
  3. * 标段项目节数据模型
  4. *
  5. * @author CaiAoLin
  6. * @date 2017/12/1
  7. * @version
  8. */
  9. module.exports = app => {
  10. class TenderNode extends app.BaseService {
  11. /**
  12. * 构造函数
  13. *
  14. * @param {Object} ctx - egg全局变量
  15. * @return {void}
  16. */
  17. constructor(ctx) {
  18. super(ctx);
  19. this.tableName = 'tender_node';
  20. }
  21. /**
  22. * 新增数据
  23. *
  24. * @param {Object} data - 新增的数据(可批量)
  25. * @param {Number} tenderId - 标段id
  26. * @return {Boolean} - 返回新增的结果
  27. */
  28. async add(data, tenderId) {
  29. this.transaction = await this.db.beginTransaction();
  30. let result = false;
  31. try {
  32. if (tenderId <= 0) {
  33. throw '标段id错误';
  34. }
  35. if (data instanceof Array) {
  36. // 数组则为批量插入
  37. if (data.length <= 0) {
  38. throw '插入数据为空';
  39. }
  40. // 整理数据
  41. const insertData = [];
  42. for (const tmp of data) {
  43. tmp.template_id = tmp.id;
  44. tmp.template_pid = tmp.pid;
  45. tmp.tender_id = tenderId;
  46. delete tmp.id;
  47. delete tmp.pid;
  48. insertData.push(tmp);
  49. }
  50. const operate = await this.transaction.insert(this.tableName, insertData);
  51. this.transaction.commit();
  52. result = operate.affectedRows > 0;
  53. } else {
  54. // 对象则单个插入
  55. }
  56. } catch (error) {
  57. result = false;
  58. }
  59. return result;
  60. }
  61. /**
  62. * 根据层级获取数据
  63. *
  64. * @param {Number} tenderId - 标段id
  65. * @param {Boolean} showAll - 是否显示全部
  66. * @return {Array} - 返回数据
  67. */
  68. async getDataByTenderId(tenderId, showAll = false) {
  69. if (tenderId <= 0) {
  70. return [];
  71. }
  72. const showLevel = !showAll ? 2 : -1;
  73. this.initSqlBuilder();
  74. this.sqlBuilder.setAndWhere('tender_id', {
  75. value: tenderId,
  76. operate: '=',
  77. });
  78. if (showLevel > 0) {
  79. this.sqlBuilder.setAndWhere('level', {
  80. value: showLevel,
  81. operate: '<=',
  82. });
  83. }
  84. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  85. const data = await this.db.query(sql, sqlParam);
  86. return data;
  87. }
  88. /**
  89. * 根据节点Id获取数据
  90. *
  91. * @param {Number} tenderId - 标段id
  92. * @param {Number} nodeId - 项目节/工程量清单节点id
  93. * @return {Object} - 返回查询到的节点数据
  94. */
  95. async getDataByNodeId(tenderId, nodeId) {
  96. if ((nodeId <= 0) || (tenderId <= 0)) {
  97. return undefined;
  98. }
  99. this.initSqlBuilder();
  100. this.sqlBuilder.setAndWhere('tender_id', {
  101. value: tenderId,
  102. operate: '=',
  103. });
  104. this.sqlBuilder.setAndWhere('template_id', {
  105. value: nodeId,
  106. operate: '=',
  107. });
  108. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  109. const data = await this.db.queryOne(sql, sqlParam);
  110. return data;
  111. }
  112. /**
  113. * 获取最末的子节点
  114. * @param {Number} tenderId - 标段id
  115. * @param {Number} pid - 父节点id
  116. * @returns {Object}
  117. */
  118. async getLastChildData(tenderId, pid) {
  119. this.initSqlBuilder();
  120. this.sqlBuilder.setAndWhere('tender_id', {
  121. value: tenderId,
  122. operate: '='
  123. });
  124. this.sqlBuilder.setAndWhere('template_pid', {
  125. value: pid,
  126. operate: '='
  127. });
  128. this.sqlBuilder.orderBy = [['order', 'DESC']];
  129. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  130. const resultData = this.db.queryOne(sql, sqlParam);
  131. return resultData;
  132. }
  133. /**
  134. * 根据 父节点id 和 节点排序order 获取数据
  135. *
  136. * @param {Number} tenderId - 标段id
  137. * @param {Number} pid - 父节点id
  138. * @param {Number|Array} order - 排序
  139. * @returns {Object|Array} - 查询结果
  140. */
  141. async getDataByParentAndOrder(tenderId, pid, order) {
  142. if ((tenderId <= 0) || (pid <= 0) || (order <= 0)) {
  143. return undefined;
  144. }
  145. this.initSqlBuilder();
  146. this.sqlBuilder.setAndWhere('tender_id', {
  147. value: tenderId,
  148. operate: '='
  149. });
  150. this.sqlBuilder.setAndWhere('template_pid', {
  151. value: pid,
  152. operate: '=',
  153. });
  154. if (order instanceof Array) {
  155. this.sqlBuilder.setAndWhere('order', {
  156. value: order,
  157. operate: 'in'
  158. });
  159. } else {
  160. this.sqlBuilder.setAndWhere('order', {
  161. value: order,
  162. operate: '='
  163. });
  164. }
  165. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  166. let data;
  167. if (order instanceof Array) {
  168. data = await this.db.query(sql, sqlParam);
  169. } else {
  170. data = await this.db.queryOne(sql, sqlParam);
  171. }
  172. return data;
  173. }
  174. /**
  175. * 根据 父节点ID 和 节点排序order 获取全部后节点数据
  176. * @param {Number} tenderId - 标段id
  177. * @param {Number} pid - 父节点id
  178. * @param {Number} order - 排序
  179. * @returns {Array}
  180. */
  181. async getNextsData(tenderId, pid, order) {
  182. if ((tenderId <= 0) || (pid <= 0) || (order <= 0)) {
  183. return undefined;
  184. }
  185. this.initSqlBuilder();
  186. this.sqlBuilder.setAndWhere('tender_id', {
  187. value: tenderId,
  188. operate: '='
  189. });
  190. this.sqlBuilder.setAndWhere('template_pid', {
  191. value: pid,
  192. operate: '=',
  193. });
  194. this.sqlBuilder.setAndWhere('order', {
  195. value: order,
  196. operate: '>'
  197. });
  198. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  199. const data = await this.db.query(sql, sqlParam);
  200. return data;
  201. }
  202. /**
  203. * select的全部后兄弟节点,Order自增
  204. *
  205. * @param {Object} select - 选中的节点
  206. * @param {Number} incre - 自增值
  207. * @return {Array} - 自增后的数据
  208. * @private
  209. */
  210. async _updateSelectNextsOrder(select, incre = 1) {
  211. this.initSqlBuilder();
  212. this.sqlBuilder.setAndWhere('tender_id', {
  213. value: select.tender_id,
  214. operate: '=',
  215. });
  216. this.sqlBuilder.setAndWhere('order', {
  217. value: select.order + 1,
  218. operate: '>=',
  219. });
  220. this.sqlBuilder.setAndWhere('template_pid', {
  221. value: select.template_pid,
  222. operate: '=',
  223. });
  224. this.sqlBuilder.setUpdateData('order', {
  225. value: Math.abs(incre),
  226. selfOperate: incre > 0 ? '+' : '-',
  227. });
  228. // sql = update this.tableName set order = order + 1 where (tender_id = select.tender_id) && (pid = select.pid) && (order >= select.order+1)
  229. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
  230. const data = await this.transaction.query(sql, sqlParam);
  231. return data;
  232. }
  233. /**
  234. * 从数据库获取标段的最大节点id
  235. *
  236. * @param {Number} tenderId - 标段id
  237. * @return {Number}
  238. * @private
  239. */
  240. async _getMaxNodeId(tenderId) {
  241. const sql = 'SELECT Max(??) As max_id FROM ?? Where tender_id = ' + tenderId;
  242. const sqlParam = ['template_id', this.tableName];
  243. const queryResult = await this.db.queryOne(sql, sqlParam);
  244. return queryResult.max_id;
  245. }
  246. /**
  247. * 根据selectData, data 新增数据
  248. *
  249. * @param {Number} tenderId - 标段id
  250. * @param {Object} selectData - 选中节点的数据
  251. * @param {Object} data - 新增节点的初始数据
  252. * @return {Object} - 新增结果
  253. * @private
  254. */
  255. async _addNodeData(tenderId, selectData, data) {
  256. if (tenderId <= 0) {
  257. return undefined;
  258. }
  259. if (!data) {
  260. data = {};
  261. }
  262. const cacheKey = 'tender_node_maxId:' + tenderId;
  263. let maxId = parseInt(await this.cache.get(cacheKey));
  264. if (!maxId) {
  265. maxId = await this._getMaxNodeId(tenderId);
  266. this.cache.set(cacheKey, maxId, 'EX', this.ctx.app.config.cacheTime);
  267. }
  268. data.tender_id = tenderId;
  269. data.template_id = maxId + 1;
  270. data.template_pid = selectData.template_pid;
  271. data.level = selectData.level;
  272. data.order = selectData.order + 1;
  273. data.full_path = selectData.full_path.replace(selectData.template_id, data.template_id);
  274. const result = await this.transaction.insert(this.tableName, data);
  275. this.cache.set(cacheKey, maxId + 1, 'EX', this.ctx.app.config.cacheTime);
  276. return result;
  277. }
  278. /**
  279. * tenderId标段中, 在selectId后新增一个节点
  280. *
  281. * @param {Number} tenderId - 标段id
  282. * @param {Number} selectId - 选中节点id
  283. * @param {Object} data - 新增节点初始化数据
  284. * @return {Array} 新增后的数据,其他被修改的数据
  285. */
  286. async addNode(tenderId, selectId, data) {
  287. if ((tenderId <= 0) || (selectId <= 0)) {
  288. return [];
  289. }
  290. const selectData = await this.getDataByNodeId(tenderId, selectId);
  291. this.transaction = await this.db.beginTransaction();
  292. if (selectData) {
  293. try {
  294. // 选中节点的所有后兄弟节点,order+1
  295. await this._updateSelectNextsOrder(selectData);
  296. // 数据库创建新增节点数据
  297. await this._addNodeData(tenderId, selectData, data);
  298. await this.transaction.commit();
  299. } catch (err) {
  300. await this.transaction.rollback();
  301. throw err;
  302. }
  303. // 查询应返回的结果
  304. this.initSqlBuilder();
  305. this.sqlBuilder.setAndWhere('tender_id', {
  306. value: selectData.tender_id,
  307. operate: '=',
  308. });
  309. this.sqlBuilder.setAndWhere('template_pid', {
  310. value: selectData.template_pid,
  311. operate: '=',
  312. });
  313. this.sqlBuilder.setAndWhere('order', {
  314. value: selectData.order,
  315. operate: '>',
  316. });
  317. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  318. const resultData = this.db.query(sql, sqlParam);
  319. return resultData;
  320. } else {
  321. throw '新增节点数据错误';
  322. }
  323. }
  324. /**
  325. * tenderId标段中, 删除选中节点及其子节点
  326. *
  327. * @param {Number} tenderId - 标段id
  328. * @param {Number} selectId - 选中节点id
  329. * @return {Array} - 被删除的数据
  330. */
  331. async deleteNode(tenderId, selectId) {
  332. if ((tenderId <= 0) || (selectId <= 0)) {
  333. return [];
  334. }
  335. const selectData = await this.getDataByNodeId(tenderId, selectId);
  336. this.transaction = await this.db.beginTransaction();
  337. let resultData = [];
  338. if (selectData) {
  339. try {
  340. // 获取将要被删除的数据
  341. this.initSqlBuilder();
  342. this.sqlBuilder.setAndWhere('tender_id', {
  343. value: tenderId,
  344. operate: '='
  345. });
  346. this.sqlBuilder.setAndWhere('full_path', {
  347. value: this.db.escape(selectData.full_path + '%'),
  348. operate: 'Like'
  349. });
  350. let [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  351. resultData = await this.db.query(sql, sqlParam);
  352. // 删除
  353. this.initSqlBuilder();
  354. this.sqlBuilder.setAndWhere('tender_id', {
  355. value: tenderId,
  356. operate: '='
  357. });
  358. this.sqlBuilder.setAndWhere('full_path', {
  359. value: this.db.escape(selectData.full_path + '%'),
  360. operate: 'Like'
  361. });
  362. [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'delete');
  363. const operate = await this.transaction.query(sql, sqlParam);
  364. this.transaction.commit();
  365. } catch(err) {
  366. resultData = [];
  367. await this.transaction.rollback();
  368. throw err;
  369. }
  370. return resultData;
  371. } else {
  372. throw '删除节点数据错误';
  373. }
  374. }
  375. /**
  376. * tenderId标段中, 选中节点selectId上移
  377. *
  378. * @param {Number} tenderId - 标段id
  379. * @param {Number} selectId - 选中节点id
  380. * @return {Array} - 发生改变的数据
  381. */
  382. async upMoveNode(tenderId, selectId) {
  383. if ((tenderId <= 0) || (selectId <= 0)) {
  384. return [];
  385. }
  386. const selectData = await this.getDataByNodeId(tenderId, selectId);
  387. const preData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, selectData.order - 1);
  388. this.transaction = await this.db.beginTransaction();
  389. if (selectData && preData) {
  390. try {
  391. const sData = await this.transaction.update(this.tableName, {id: selectData.id, order: selectData.order - 1});
  392. const pData = await this.transaction.update(this.tableName, {id: preData.id, order: preData.order + 1});
  393. this.transaction.commit();
  394. } catch (err) {
  395. await this.transaction.rollback();
  396. throw err;
  397. }
  398. const resultData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, [selectData.order, preData.order]);
  399. return resultData;
  400. } else {
  401. throw '上移节点数据错误';
  402. }
  403. }
  404. /**
  405. * tenderId标段中, 选中节点selectId下移
  406. *
  407. * @param {Number} tenderId - 标段id
  408. * @param {Number} selectId - 选中节点id
  409. * @return {Array} - 发生改变的数据
  410. */
  411. async downMoveNode(tenderId, selectId) {
  412. if ((tenderId <= 0) || (selectId <= 0)) {
  413. return [];
  414. }
  415. const selectData = await this.getDataByNodeId(tenderId, selectId);
  416. const nextData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, selectData.order + 1);
  417. this.transaction = await this.db.beginTransaction();
  418. if (selectData && nextData) {
  419. try {
  420. const sData = await this.transaction.update(this.tableName, {id: selectData.id, order: selectData.order + 1});
  421. const pData = await this.transaction.update(this.tableName, {id: nextData.id, order: nextData.order - 1});
  422. this.transaction.commit();
  423. } catch (err) {
  424. await this.transaction.rollback();
  425. throw err;
  426. }
  427. const resultData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, [selectData.order, nextData.order]);
  428. return resultData;
  429. } else {
  430. throw '下移节点数据错误';
  431. }
  432. }
  433. /**
  434. * 升级selectData, 同步修改所有子节点
  435. * @param {Object} selectData - 升级操作,选中节点
  436. * @return {Object}
  437. * @private
  438. */
  439. async _syncUplevelChildren(selectData) {
  440. this.initSqlBuilder();
  441. this.sqlBuilder.setAndWhere('tender_id', {
  442. value: selectData.tender_id,
  443. operate: '='
  444. });
  445. this.sqlBuilder.setAndWhere('full_path', {
  446. value: this.db.escape(selectData.full_path + '.%'),
  447. operate: 'like'
  448. });
  449. this.sqlBuilder.setUpdateData('level', {
  450. value: 1,
  451. selfOperate: '-'
  452. });
  453. this.sqlBuilder.setUpdateData('full_path', {
  454. value: ['`full_path`', this.db.escape(selectData.template_pid + '.'), this.db.escape('')],
  455. literal: 'Replace'
  456. });
  457. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
  458. const data = this.transaction.query(sql, sqlParam);
  459. return data;
  460. }
  461. /**
  462. * 选中节点的后兄弟节点,全部变为当前节点的子节点
  463. * @param {Object} selectData - 选中节点
  464. * @return {Object}
  465. * @private
  466. */
  467. async _syncUpLevelNexts(selectData) {
  468. // 查询selectData的lastChild
  469. const lastChildData = await this.getLastChildData(selectData.tender_id, selectData.template_id);
  470. const nextsData = await this.getNextsData(selectData.tender_id, selectData.template_pid, selectData.order);
  471. if (nextsData && nextsData.length > 0) {
  472. // 修改nextsData pid, 排序
  473. this.initSqlBuilder();
  474. this.sqlBuilder.setUpdateData('template_pid', {
  475. value: selectData.template_id
  476. });
  477. const orderInc = lastChildData ? lastChildData.order - selectData.order : - selectData.order;
  478. this.sqlBuilder.setUpdateData('order', {
  479. value: Math.abs(orderInc),
  480. selfOperate: orderInc > 0 ? '+' : '-'
  481. });
  482. this.sqlBuilder.setAndWhere('template_pid', {
  483. value: selectData.template_pid,
  484. operate: '='
  485. });
  486. this.sqlBuilder.setAndWhere('order', {
  487. value: selectData.order,
  488. operate: '>'
  489. });
  490. const [sql1, sqlParam1] = this.sqlBuilder.build(this.tableName, 'update');
  491. await this.transaction.query(sql1, sqlParam1);
  492. // 修改nextsData及其子节点的full_path
  493. const oldSubStr = this.db.escape(selectData.template_pid + '.');
  494. const newSubStr = this.db.escape(selectData.template_id + '.');
  495. const sqlArr = [];
  496. sqlArr.push('Update ?? SET `full_path` = Replace(`full_path`,' + oldSubStr + ',' + newSubStr + ') Where');
  497. sqlArr.push('(`tender_id` = ' + selectData.tender_id +')');
  498. sqlArr.push(' And (');
  499. for (const data of nextsData) {
  500. sqlArr.push('`full_path` Like ' + this.db.escape(data.full_path + '%'));
  501. if (nextsData.indexOf(data) < nextsData.length - 1) {
  502. sqlArr.push(' Or ');
  503. }
  504. }
  505. sqlArr.push(')');
  506. const sql = sqlArr.join('');
  507. const resultData = await this.transaction.query(sql, [this.tableName]);
  508. return resultData;
  509. }
  510. }
  511. /**
  512. * 升级节点
  513. *
  514. * @param {Number} tenderId - 标段id
  515. * @param {Number} selectId - 选中节点id
  516. * @return {Array} - 发生改变的数据
  517. */
  518. async upLevelNode(tenderId, selectId) {
  519. if ((tenderId <= 0) || (selectId <= 0)) {
  520. return [];
  521. }
  522. const selectData = await this.getDataByNodeId(tenderId, selectId);
  523. if (!selectData) {
  524. throw '升级节点数据错误';
  525. }
  526. const parentData = await this.getDataByNodeId(tenderId, selectData.template_pid);
  527. if (!parentData) {
  528. throw '升级节点数据错误'
  529. }
  530. this.transaction = await this.db.beginTransaction();
  531. try {
  532. // 选中节点--父节点--全部后兄弟节点 order+1
  533. await this._updateSelectNextsOrder(parentData);
  534. // 选中节点 修改pid, order, full_path
  535. const updateData = {id: selectData.id,
  536. template_pid: parentData.template_pid,
  537. order: parentData.order + 1,
  538. level: selectData.level - 1,
  539. full_path: selectData.full_path.replace(selectData.template_pid + '.', '')
  540. };
  541. await this.transaction.update(this.tableName, updateData);
  542. // 选中节点--全部子节点(含孙) level-1, full_path变更
  543. await this._syncUplevelChildren(selectData);
  544. // 选中节点--全部后兄弟节点 收编为子节点 修改pid, order, full_path
  545. await this._syncUpLevelNexts(selectData);
  546. this.transaction.commit();
  547. } catch (err) {
  548. await this.transaction.rollback();
  549. throw err;
  550. }
  551. // 查询修改的数据
  552. this.initSqlBuilder();
  553. this.sqlBuilder.setAndWhere('tender_id', {
  554. value: tenderId,
  555. operate: '='
  556. });
  557. this.sqlBuilder.setAndWhere('full_path', {
  558. value: this.db.escape(selectData.full_path.replace(selectData.template_pid + '.', '') + '%'),
  559. operate: 'Like'
  560. });
  561. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  562. const resultData1 = await this.db.query(sql, sqlParam);
  563. const resultData2 = await this.getNextsData(tenderId, parentData.template_pid, parentData.order + 1);
  564. return resultData1.concat(resultData2);
  565. }
  566. /**
  567. * 降级selectData, 同步修改所有子节点
  568. * @param {Object} selectData - 选中节点
  569. * @param {Object} preData - 选中节点的前一节点(降级后为父节点)
  570. * @returns {Promise<*>}
  571. * @private
  572. */
  573. async _syncDownlevelChildren(selectData, preData) {
  574. this.initSqlBuilder();
  575. this.sqlBuilder.setAndWhere('tender_id', {
  576. value: selectData.tender_id,
  577. operate: '='
  578. });
  579. this.sqlBuilder.setAndWhere('full_path', {
  580. value: this.db.escape(selectData.full_path + '.%'),
  581. operate: 'like'
  582. });
  583. this.sqlBuilder.setUpdateData('level', {
  584. value: 1,
  585. selfOperate: '+'
  586. });
  587. this.sqlBuilder.setUpdateData('full_path', {
  588. value: ['`full_path`', this.db.escape(selectData.template_id), this.db.escape(preData.template_id + '.' + selectData.template_id)],
  589. literal: 'Replace'
  590. });
  591. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
  592. const data = this.transaction.query(sql, sqlParam);
  593. return data;
  594. }
  595. /**
  596. * 降级节点
  597. *
  598. * @param {Number} tenderId - 标段id
  599. * @param {Number} selectId - 选中节点id
  600. * @return {Array} - 发生改变的数据
  601. */
  602. async downLevelNode(tenderId, selectId) {
  603. if ((tenderId <= 0) || (selectId <= 0)) {
  604. return [];
  605. }
  606. const selectData = await this.getDataByNodeId(tenderId, selectId);
  607. if (!selectData) {
  608. throw '降级节点数据错误';
  609. }
  610. const preData = await this.getDataByParentAndOrder(tenderId, selectData.template_pid, selectData.order-1);
  611. if (!preData) {
  612. throw '节点不可降级';
  613. }
  614. const preLastChildData = await this.getLastChildData(tenderId, preData.template_id);
  615. this.transaction = await this.db.beginTransaction();
  616. try {
  617. // 选中节点--全部后节点 order--
  618. await this._updateSelectNextsOrder(selectData, -1);
  619. // 选中节点 修改pid, level, order, full_path
  620. const updateData = {id: selectData.id,
  621. template_pid: preData.template_pid,
  622. order: preLastChildData ? preLastChildData.order + 1 : 1,
  623. level: selectData.level + 1,
  624. full_path: selectData.full_path.replace(selectData.template_id, preData.template_id + '.' + selectData.template_id)
  625. };
  626. await this.transaction.update(this.tableName, updateData);
  627. // 选中节点--全部子节点(含孙) level++, full_path
  628. await this._syncDownlevelChildren(selectData, preData);
  629. this.transaction.commit();
  630. } catch (err) {
  631. this.transaction.rollback();
  632. throw err;
  633. }
  634. // 查询修改的数据
  635. this.initSqlBuilder();
  636. this.sqlBuilder.setAndWhere('tender_id', {
  637. value: tenderId,
  638. operate: '='
  639. });
  640. this.sqlBuilder.setAndWhere('full_path', {
  641. value: this.db.escape(selectData.full_path.replace(selectData.template_id, preData.template_id + '.' + selectData.template_id) + '%'),
  642. operate: 'Like'
  643. });
  644. const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
  645. const resultData1 = await this.db.query(sql, sqlParam);
  646. const resultData2 = await this.getNextsData(tenderId, preData.template_pid, preData.order);
  647. return resultData1.concat(resultData2);
  648. }
  649. }
  650. return TenderNode;
  651. };