ledger_controller.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. 'use strict';
  2. /**
  3. * 台账相关控制器
  4. *
  5. * @author CaiAoLin
  6. * @date 2017/11/30
  7. * @version
  8. */
  9. const stdDataAddType = {
  10. self: 1,
  11. withParent: 2
  12. }
  13. const auditConst = require('../const/audit').flow;
  14. const spreadConst = require('../const/spread');
  15. module.exports = app => {
  16. class LedgerController extends app.BaseController {
  17. /**
  18. * 构造函数
  19. *
  20. * @param {Object} ctx - egg全局变量
  21. * @return {void}
  22. */
  23. constructor(ctx) {
  24. super(ctx);
  25. ctx.showProject = true;
  26. ctx.showTitle = true;
  27. ctx.showTender = true;
  28. }
  29. /**
  30. * 台账分解页面 (Get)
  31. *
  32. * @param {Object} ctx - egg全局变量
  33. * @return {void}
  34. */
  35. async explode(ctx) {
  36. try {
  37. const tenderId = ctx.params.id;
  38. const tenderList = await this.service.tender.getList();
  39. const tenderData = await this.service.tender.getDataById(tenderId);
  40. if (!tenderData.ledger_status) {
  41. tenderData.ledger_status = auditConst.status.uncheck;
  42. }
  43. if (!tenderData.ledger_times) {
  44. tenderData.ledger_times = 1;
  45. }
  46. const curAuditor = await ctx.service.ledgerAudit.getCurAuditor(tenderId, tenderData.ledger_times);
  47. const times = tenderData.ledger_status === auditConst.status.checkNo ? tenderData.ledger_times - 1 : tenderData.ledger_times;
  48. const auditors = await ctx.service.ledgerAudit.getAuditors(tenderId, times);
  49. const content = auditors.length > 0 ? await ctx.service.ledgerAuditContent.getAllDataByCondition({
  50. where: {tender_id: tenderId, times: times, audit_id: auditors[0].audit_id}
  51. }) : null;
  52. const ledgerData = await ctx.service.ledger.getDataByTenderId(tenderId, 4);
  53. const renderData = {
  54. tenderData,
  55. auditConst,
  56. auditors,
  57. curAuditor,
  58. content,
  59. ledger: JSON.stringify(ledgerData),
  60. ledgerSpreadSetting: JSON.stringify(spreadConst.ledgerSpread),
  61. tenderList,
  62. };
  63. await this.layout('ledger/explode.ejs', renderData, 'ledger/explode_modal.ejs');
  64. } catch (err) {
  65. console.log(err);
  66. await this.layout('/dashboard');
  67. }
  68. }
  69. /**
  70. * 检查标段是否只读(审核中,审核完成)
  71. * @param {Object} tenderData
  72. * @returns {boolean}
  73. * @private
  74. */
  75. _ledgerReadOnly (tenderData) {
  76. return tenderData.ledger_status === auditConst.status.checking || tenderData.ledger_status === auditConst.status.checked;
  77. }
  78. /**
  79. * 获取子节点 (Ajax)
  80. * @param ctx
  81. * @return {Promise<void>}
  82. */
  83. async getChildren(ctx) {
  84. const responseData = {
  85. err: 0,
  86. msg: '',
  87. data: [],
  88. };
  89. try {
  90. const tenderId = ctx.params.id;
  91. if (!tenderId) {
  92. throw '当前未打开标段';
  93. }
  94. const data = JSON.parse(ctx.request.body.data);
  95. const id = data.ledger_id;
  96. if (isNaN(id) || id <= 0) {
  97. throw '参数错误';
  98. }
  99. responseData.data = await ctx.service.ledger.getChildrenByParentId(tenderId, id);
  100. } catch (err) {
  101. responseData.err = 1;
  102. responseData.msg = err;
  103. }
  104. ctx.body = responseData;
  105. }
  106. /**
  107. * 树结构基本操作(增、删、上下移、升降级)(Ajax)
  108. * @param {Object} ctx - egg全局变量
  109. * @return {Promise<void>}
  110. */
  111. async baseOperation(ctx) {
  112. const responseData = {
  113. err: 0,
  114. msg: '',
  115. data: [],
  116. };
  117. try {
  118. const tenderId = ctx.params.id;
  119. if (!tenderId) {
  120. throw '当前未打开标段';
  121. }
  122. const tenderData = await ctx.service.tender.getDataById(tenderId);
  123. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  124. throw '标段数据错误';
  125. }
  126. const data = JSON.parse(ctx.request.body.data);
  127. if ((isNaN(data.id) || data.id <= 0) || (!data.postType)) {
  128. throw '参数错误';
  129. }
  130. switch (data.postType) {
  131. case 'add':
  132. responseData.data = await ctx.service.ledger.addNode(tenderId, data.id);
  133. break;
  134. case 'delete':
  135. responseData.data = await ctx.service.ledger.deleteNode(tenderId, data.id);
  136. break;
  137. case 'up-move':
  138. responseData.data = await ctx.service.ledger.upMoveNode(tenderId, data.id);
  139. break;
  140. case 'down-move':
  141. responseData.data = await ctx.service.ledger.downMoveNode(tenderId, data.id);
  142. break;
  143. case 'up-level':
  144. responseData.data = await ctx.service.ledger.upLevelNode(tenderId, data.id);
  145. break;
  146. case 'down-level':
  147. responseData.data = await ctx.service.ledger.downLevelNode(tenderId, data.id);
  148. break;
  149. default:
  150. throw '未知操作';
  151. }
  152. } catch (err) {
  153. responseData.err = 1;
  154. responseData.msg = err;
  155. console.log(err);
  156. }
  157. ctx.body = responseData;
  158. }
  159. /**
  160. * 提交更新数据 (Ajax)
  161. * @param ctx
  162. * @return {Promise<void>}
  163. */
  164. async updateInfo(ctx) {
  165. const responseData = {
  166. err: 0,
  167. msg: '',
  168. data: [],
  169. };
  170. try {
  171. const tenderId = ctx.params.id;
  172. if (!tenderId) {
  173. throw '当前未打开标段';
  174. }
  175. const tenderData = await ctx.service.tender.getDataById(tenderId);
  176. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  177. throw '标段数据错误';
  178. }
  179. const data = JSON.parse(ctx.request.body.data);
  180. if (data instanceof Array) {
  181. responseData.data = await ctx.service.ledger.updateInfos(tenderId, data);
  182. } else {
  183. responseData.data = await ctx.service.ledger.updateInfo(tenderId, data);
  184. }
  185. } catch (err) {
  186. responseData.err = 1;
  187. responseData.msg = err;
  188. }
  189. ctx.body = responseData;
  190. }
  191. async update(ctx) {
  192. const responseData = {
  193. err: 0,
  194. msg: '',
  195. data: [],
  196. };
  197. try {
  198. const tenderId = ctx.params.id;
  199. if (!tenderId) {
  200. throw '当前未打开标段';
  201. }
  202. const tenderData = await ctx.service.tender.getDataById(tenderId);
  203. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  204. throw '标段数据错误';
  205. }
  206. const data = JSON.parse(ctx.request.body.data);
  207. responseData.data = await ctx.service.ledger.updateCalc(tenderId, data);
  208. } catch (err) {
  209. responseData.err = 1;
  210. responseData.msg = err;
  211. }
  212. ctx.body = responseData;
  213. }
  214. /**
  215. * 复制粘贴整块 (Ajax)
  216. *
  217. * @param ctx
  218. * @return {Promise<void>}
  219. */
  220. async pasteBlock(ctx) {
  221. const responseData = {
  222. err: 0,
  223. msg: '',
  224. data: [],
  225. };
  226. try {
  227. const tenderId = ctx.params.id;
  228. if (!tenderId) {
  229. throw '当前未打开标段';
  230. }
  231. const tenderData = await ctx.service.tender.getDataById(tenderId);
  232. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  233. throw '标段数据错误';
  234. }
  235. const data = JSON.parse(ctx.request.body.data);
  236. if ((isNaN(data.id) || data.id <= 0) || (!data.block || data.block.length <= 0)) {
  237. throw '参数错误';
  238. }
  239. responseData.data = await ctx.service.ledger.pasteBlock(tenderId, data.id, data.block);
  240. } catch (err) {
  241. responseData.err = 1;
  242. responseData.msg = err;
  243. }
  244. ctx.body = responseData;
  245. }
  246. /**
  247. * 从标准项目表添加数据 (Ajax)
  248. * @param ctx
  249. * @returns {Promise<void>}
  250. */
  251. async addFromStandardLib(ctx) {
  252. const responseData = {
  253. err: 0,
  254. msg: '',
  255. data: [],
  256. };
  257. try {
  258. const tenderId = ctx.params.id;
  259. if (!tenderId) {
  260. throw '当前未打开标段';
  261. }
  262. const tenderData = await ctx.service.tender.getDataById(tenderId);
  263. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  264. throw '标段数据错误';
  265. }
  266. const data = JSON.parse(ctx.request.body.data);
  267. if ((isNaN(data.id) || data.id <= 0) || !data.stdType || !data.stdNode) {
  268. throw '参数错误';
  269. }
  270. //todo 校验项目是否使用该库的权限
  271. let stdLib;
  272. switch (data.stdType) {
  273. case 'chapter':
  274. stdLib = ctx.service.stdChapter;
  275. break;
  276. case 'bills':
  277. stdLib = ctx.service.stdBills;
  278. break;
  279. default:
  280. throw '未知标准库';
  281. }
  282. const stdData = await stdLib.getDataByDataId(data.stdLibId, data.stdNode);
  283. const addType = stdDataAddType.withParent;
  284. switch (addType) {
  285. case stdDataAddType.self:
  286. responseData.data = await ctx.service.ledger.addStdNode(tenderId, data.id, stdData);
  287. break;
  288. case stdDataAddType.withParent:
  289. responseData.data = await ctx.service.ledger.addStdNodeWithParent(tenderId, stdData, stdLib);
  290. break;
  291. default:
  292. throw '未知添加方法';
  293. }
  294. } catch (err) {
  295. responseData.err = 1;
  296. responseData.msg = err;
  297. }
  298. ctx.body = responseData;
  299. }
  300. /**
  301. * 批量插入数据 (Ajax)
  302. *
  303. * data = {id, batchData, batchType}
  304. * data.batchType = 'batchInsertChild'/'batchInsertNext'
  305. * data.batchData = [{name, children}] -- 项目节列表
  306. * data.batchData.children = [{code, name, unit, unit_price, quantity}] -- 工程量清单列表
  307. *
  308. * @param ctx
  309. * @returns {Promise<void>}
  310. */
  311. async batchInsert(ctx) {
  312. const responseData = {
  313. err: 0,
  314. msg: '',
  315. data: [],
  316. };
  317. try {
  318. const tenderId = ctx.params.id;
  319. if (!tenderId) {
  320. throw '当前未打开标段';
  321. }
  322. const tenderData = await ctx.service.tender.getDataById(tenderId);
  323. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  324. throw '标段数据错误';
  325. }
  326. const data = JSON.parse(ctx.request.body.data);
  327. if ((isNaN(data.id) || data.id <= 0) || !data.batchType) {
  328. throw '参数错误';
  329. }
  330. switch (data.batchType) {
  331. case 'batchInsertChild':
  332. responseData.data = await ctx.service.ledger.batchInsertChild(tenderId, data.id, data.batchData);
  333. break;
  334. case 'batchInsertNext':
  335. responseData.data = await ctx.service.ledger.batchInsertNext(tenderId, data.id, data.batchData);
  336. break;
  337. default:
  338. throw '参数错误';
  339. }
  340. } catch (err) {
  341. responseData.err = 1;
  342. responseData.msg = err;
  343. }
  344. ctx.body = responseData;
  345. }
  346. /**
  347. * 查询
  348. *
  349. * @param ctx
  350. * @returns {Promise<void>}
  351. */
  352. async search(ctx) {
  353. const responseData = {
  354. err: 0,
  355. msg: '',
  356. data: [],
  357. };
  358. try {
  359. const tenderId = ctx.params.id;
  360. if (!tenderId) {
  361. throw '当前未打开标段';
  362. }
  363. const data = JSON.parse(ctx.request.body.data);
  364. if (!data.keyword || data.keyword === '') {
  365. throw '参数错误';
  366. }
  367. responseData.data = await ctx.service.ledger.search(tenderId, {
  368. value: ctx.app.mysql.escape('%' + data.keyword + '%'),
  369. operate: 'Like',
  370. fields: ['code', 'b_code', 'name'],
  371. });
  372. } catch (err) {
  373. console.log(err);
  374. responseData.err = 1;
  375. responseData.msg = err;
  376. }
  377. ctx.body = responseData;
  378. }
  379. /**
  380. * 定位
  381. * @param ctx
  382. * @returns {Promise<void>}
  383. */
  384. async locate(ctx) {
  385. const responseData = {
  386. err: 0,
  387. msg: '',
  388. data: [],
  389. };
  390. try {
  391. const tenderId = ctx.params.id;
  392. if (!tenderId) {
  393. throw '当前未打开标段';
  394. }
  395. const data = JSON.parse(ctx.request.body.data);
  396. if ((isNaN(data.id) || data.id <= 0)) {
  397. throw '参数错误';
  398. }
  399. responseData.data = await ctx.service.ledger.locateNode(tenderId, data.id);
  400. } catch (err) {
  401. console.log(err);
  402. responseData.err = 1;
  403. responseData.msg = err;
  404. }
  405. ctx.body = responseData;
  406. }
  407. /**
  408. * 获取全部子节点
  409. *
  410. * @param ctx
  411. * @returns {Promise<void>}
  412. */
  413. async posterity(ctx) {
  414. const responseData = {
  415. err: 0,
  416. msg: '',
  417. data: [],
  418. };
  419. try {
  420. const tenderId = ctx.params.id;
  421. if (!tenderId) {
  422. throw '当前未打开标段';
  423. }
  424. const data = JSON.parse(ctx.request.body.data);
  425. if ((isNaN(data.id) || data.id <= 0)) {
  426. throw '参数错误';
  427. }
  428. const expandData = await ctx.service.ledger.getPosterityByParentId(tenderId, data.id);
  429. responseData.data = { expand: expandData };
  430. } catch (err) {
  431. console.log(err);
  432. responseData.err = 1;
  433. responseData.msg = err;
  434. }
  435. ctx.body = responseData;
  436. }
  437. /**
  438. * 台账变更页面 (Get)
  439. *
  440. * @param {object} ctx - egg全局变量
  441. * @return {void}
  442. */
  443. async change(ctx) {
  444. const renderData = {};
  445. await this.layout('ledger/change.ejs', renderData, 'ledger/change_modal.ejs');
  446. }
  447. /**
  448. * 计量台账页面 (Get)
  449. *
  450. * @param {object} ctx - egg全局变量
  451. * @return {void}
  452. */
  453. async index(ctx) {
  454. const renderData = {};
  455. await this.layout('ledger/index.ejs', renderData);
  456. }
  457. }
  458. return LedgerController;
  459. };