ledger_controller.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  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');
  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. * 台账分解页面
  31. *
  32. * @param {Object} ctx - egg全局变量
  33. * @return {void}
  34. */
  35. async explode(ctx) {
  36. if (ctx.request.query.tenderId) {
  37. const tenderId = parseInt(ctx.request.query.tenderId);
  38. const tender = await ctx.service.tender.getDataById(tenderId);
  39. ctx.session.sessionUser.tenderId = tender.id;
  40. ctx.session.sessionUser.tenderName = tender.name;
  41. ctx.redirect('/ledger/explode');
  42. } else {
  43. let tenderId = ctx.session.sessionUser.tenderId;
  44. const tenderList = await ctx.service.tender.getList();
  45. for (const tender of tenderList) {
  46. tender.url = ctx.menuList.ledger.children.explode.url + '?tenderId=' + tender.id;
  47. }
  48. if (!tenderId) {
  49. // 根据标段列表获取默认tenderId
  50. if (tenderList && tenderList.length > 0) {
  51. tenderId = tenderList[0].id;
  52. ctx.session.sessionUser.tenderId = tenderId;
  53. ctx.session.sessionUser.tenderName = tenderList[0].name;
  54. } else {
  55. throw '项目无标段数据';
  56. }
  57. }
  58. const tenderData = await ctx.service.tender.getDataById(tenderId);
  59. if (!tenderData.ledger_status) {
  60. tenderData.ledger_status = auditConst.status.uncheck;
  61. }
  62. if (!tenderData.ledger_times) {
  63. tenderData.ledger_times = 1;
  64. }
  65. const curAuditor = await ctx.service.ledgerAudit.getCurAuditor(tenderId, tenderData.ledger_times);
  66. const auditors = await ctx.service.ledgerAudit.getAuditors(tenderId, tenderData.ledger_times);
  67. const times = tenderData.ledger_status === auditConst.status.checkNo ? tenderData.ledger_times - 1 : tenderData.ledger_times;
  68. const content = await ctx.service.ledgerAuditContent.getAllDataByCondition({
  69. where: {tender_id: tenderId, times: times, audit_id: auditors[0].audit_id}
  70. });
  71. const ledgerData = await ctx.service.ledger.getDataByTenderId(tenderId);
  72. const renderData = {
  73. tenderData,
  74. auditConst,
  75. auditors,
  76. curAuditor,
  77. content,
  78. ledger: JSON.stringify(ledgerData),
  79. ledgerSpreadSetting: JSON.stringify(spreadConst.ledgerSpread),
  80. tenderList,
  81. };
  82. await this.layout('ledger/explode.ejs', renderData, 'ledger/explode_modal.ejs');
  83. }
  84. }
  85. /**
  86. * 检查标段是否只读(审核中,审核完成)
  87. * @param {Object} tenderData
  88. * @returns {boolean}
  89. * @private
  90. */
  91. _ledgerReadOnly (tenderData) {
  92. return tenderData.ledger_status === auditConst.status.checking || tenderData.ledger_status === auditConst.status.checked;
  93. }
  94. /**
  95. * 获取子节点
  96. * @param ctx
  97. * @return {Promise<void>}
  98. */
  99. async getChildren(ctx) {
  100. const responseData = {
  101. err: 0,
  102. msg: '',
  103. data: [],
  104. };
  105. try {
  106. const tenderId = ctx.session.sessionUser.tenderId;
  107. if (!tenderId) {
  108. throw '当前未打开标段';
  109. }
  110. const data = JSON.parse(ctx.request.body.data);
  111. const id = data.ledger_id;
  112. if (isNaN(id) || id <= 0) {
  113. throw '参数错误';
  114. }
  115. responseData.data = await ctx.service.ledger.getChildrenByParentId(tenderId, id);
  116. } catch (err) {
  117. responseData.err = 1;
  118. responseData.msg = err;
  119. }
  120. ctx.body = responseData;
  121. }
  122. /**
  123. * 树结构基本操作(增、删、上下移、升降级)
  124. * @param {Object} ctx - egg全局变量
  125. * @return {Promise<void>}
  126. */
  127. async baseOperation(ctx) {
  128. const responseData = {
  129. err: 0,
  130. msg: '',
  131. data: [],
  132. };
  133. try {
  134. const tenderId = ctx.session.sessionUser.tenderId;
  135. if (!tenderId) {
  136. throw '当前未打开标段';
  137. }
  138. const tenderData = await ctx.service.tender.getDataById(tenderId);
  139. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  140. throw '标段数据错误';
  141. }
  142. const data = JSON.parse(ctx.request.body.data);
  143. if ((isNaN(data.id) || data.id <= 0) || (!data.postType)) {
  144. throw '参数错误';
  145. }
  146. switch (data.postType) {
  147. case 'add':
  148. responseData.data = await ctx.service.ledger.addNode(tenderId, data.id);
  149. break;
  150. case 'delete':
  151. responseData.data = await ctx.service.ledger.deleteNode(tenderId, data.id);
  152. break;
  153. case 'up-move':
  154. responseData.data = await ctx.service.ledger.upMoveNode(tenderId, data.id);
  155. break;
  156. case 'down-move':
  157. responseData.data = await ctx.service.ledger.downMoveNode(tenderId, data.id);
  158. break;
  159. case 'up-level':
  160. responseData.data = await ctx.service.ledger.upLevelNode(tenderId, data.id);
  161. break;
  162. case 'down-level':
  163. responseData.data = await ctx.service.ledger.downLevelNode(tenderId, data.id);
  164. break;
  165. default:
  166. throw '未知操作';
  167. }
  168. } catch (err) {
  169. responseData.err = 1;
  170. responseData.msg = err;
  171. console.log(err);
  172. }
  173. ctx.body = responseData;
  174. }
  175. /**
  176. * 提交更新数据
  177. * @param ctx
  178. * @return {Promise<void>}
  179. */
  180. async updateInfo(ctx) {
  181. const responseData = {
  182. err: 0,
  183. msg: '',
  184. data: [],
  185. };
  186. try {
  187. const tenderId = ctx.session.sessionUser.tenderId;
  188. if (!tenderId) {
  189. throw '当前未打开标段';
  190. }
  191. const tenderData = await ctx.service.tender.getDataById(tenderId);
  192. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  193. throw '标段数据错误';
  194. }
  195. const data = JSON.parse(ctx.request.body.data);
  196. if (data instanceof Array) {
  197. responseData.data = await ctx.service.ledger.updateInfos(tenderId, data);
  198. } else {
  199. responseData.data = await ctx.service.ledger.updateInfo(tenderId, data);
  200. }
  201. } catch (err) {
  202. responseData.err = 1;
  203. responseData.msg = err;
  204. }
  205. ctx.body = responseData;
  206. }
  207. async update(ctx) {
  208. const responseData = {
  209. err: 0,
  210. msg: '',
  211. data: [],
  212. };
  213. try {
  214. const tenderId = ctx.session.sessionUser.tenderId;
  215. if (!tenderId) {
  216. throw '当前未打开标段';
  217. }
  218. const tenderData = await ctx.service.tender.getDataById(tenderId);
  219. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  220. throw '标段数据错误';
  221. }
  222. const data = JSON.parse(ctx.request.body.data);
  223. responseData.data = await ctx.service.ledger.updateCalc(tenderId, data);
  224. } catch (err) {
  225. responseData.err = 1;
  226. responseData.msg = err;
  227. }
  228. ctx.body = responseData;
  229. }
  230. /**
  231. * 复制粘贴整块
  232. * @param ctx
  233. * @return {Promise<void>}
  234. */
  235. async pasteBlock(ctx) {
  236. const responseData = {
  237. err: 0,
  238. msg: '',
  239. data: [],
  240. };
  241. try {
  242. const tenderId = ctx.session.sessionUser.tenderId;
  243. if (!tenderId) {
  244. throw '当前未打开标段';
  245. }
  246. const tenderData = await ctx.service.tender.getDataById(tenderId);
  247. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  248. throw '标段数据错误';
  249. }
  250. const data = JSON.parse(ctx.request.body.data);
  251. if ((isNaN(data.id) || data.id <= 0) || (!data.block || data.block.length <= 0)) {
  252. throw '参数错误';
  253. }
  254. responseData.data = await ctx.service.ledger.pasteBlock(tenderId, data.id, data.block);
  255. } catch (err) {
  256. responseData.err = 1;
  257. responseData.msg = err;
  258. }
  259. ctx.body = responseData;
  260. }
  261. /**
  262. * 从标准项目表添加数据
  263. * @param ctx
  264. * @returns {Promise<void>}
  265. */
  266. async addFromStandardLib(ctx) {
  267. const responseData = {
  268. err: 0,
  269. msg: '',
  270. data: [],
  271. };
  272. try {
  273. const tenderId = ctx.session.sessionUser.tenderId;
  274. if (!tenderId) {
  275. throw '当前未打开标段';
  276. }
  277. const tenderData = await ctx.service.tender.getDataById(tenderId);
  278. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  279. throw '标段数据错误';
  280. }
  281. const data = JSON.parse(ctx.request.body.data);
  282. if ((isNaN(data.id) || data.id <= 0) || !data.stdType || !data.stdNode) {
  283. throw '参数错误';
  284. }
  285. //todo 校验项目是否使用该库的权限
  286. let stdLib;
  287. switch (data.stdType) {
  288. case 'chapter':
  289. stdLib = ctx.service.stdChapter;
  290. break;
  291. case 'bills':
  292. stdLib = ctx.service.stdBills;
  293. break;
  294. default:
  295. throw '未知标准库';
  296. }
  297. const stdData = await stdLib.getDataByDataId(data.stdLibId, data.stdNode);
  298. const addType = stdDataAddType.withParent;
  299. switch (addType) {
  300. case stdDataAddType.self:
  301. responseData.data = await ctx.service.ledger.addStdNode(tenderId, data.id, stdData);
  302. break;
  303. case stdDataAddType.withParent:
  304. responseData.data = await ctx.service.ledger.addStdNodeWithParent(tenderId, stdData, stdLib);
  305. break;
  306. default:
  307. throw '未知添加方法';
  308. }
  309. } catch (err) {
  310. responseData.err = 1;
  311. responseData.msg = err;
  312. }
  313. ctx.body = responseData;
  314. }
  315. /**
  316. * 批量插入数据
  317. *
  318. * data = {id, batchData, batchType}
  319. * data.batchType = 'batchInsertChild'/'batchInsertNext'
  320. * data.batchData = [{name, children}] -- 项目节列表
  321. * data.batchData.children = [{code, name, unit, unit_price, quantity}] -- 工程量清单列表
  322. *
  323. * @param ctx
  324. * @returns {Promise<void>}
  325. */
  326. async batchInsert(ctx) {
  327. const responseData = {
  328. err: 0,
  329. msg: '',
  330. data: [],
  331. };
  332. try {
  333. const tenderId = ctx.session.sessionUser.tenderId;
  334. if (!tenderId) {
  335. throw '当前未打开标段';
  336. }
  337. const tenderData = await ctx.service.tender.getDataById(tenderId);
  338. if (!tenderData || tenderData.user_id !== ctx.session.sessionUser.accountId || this._ledgerReadOnly(tenderData)) {
  339. throw '标段数据错误';
  340. }
  341. const data = JSON.parse(ctx.request.body.data);
  342. if ((isNaN(data.id) || data.id <= 0) || !data.batchType) {
  343. throw '参数错误';
  344. }
  345. switch (data.batchType) {
  346. case 'batchInsertChild':
  347. responseData.data = await ctx.service.ledger.batchInsertChild(tenderId, data.id, data.batchData);
  348. break;
  349. case 'batchInsertNext':
  350. responseData.data = await ctx.service.ledger.batchInsertNext(tenderId, data.id, data.batchData);
  351. break;
  352. default:
  353. throw '参数错误';
  354. }
  355. } catch (err) {
  356. responseData.err = 1;
  357. responseData.msg = err;
  358. }
  359. ctx.body = responseData;
  360. }
  361. /**
  362. * 台账变更页面
  363. *
  364. * @param {object} ctx - egg全局变量
  365. * @return {void}
  366. */
  367. async change(ctx) {
  368. const renderData = {};
  369. await this.layout('ledger/change.ejs', renderData);
  370. }
  371. /**
  372. * 计量台账页面
  373. *
  374. * @param {object} ctx - egg全局变量
  375. * @return {void}
  376. */
  377. async index(ctx) {
  378. const renderData = {};
  379. await this.layout('ledger/index.ejs', renderData);
  380. }
  381. }
  382. return LedgerController;
  383. };