stage_controller.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date 2018/6/20
  7. * @version
  8. */
  9. const moment = require('moment');
  10. const auditConst = require('../const/audit');
  11. const spreadConst = require('../const/spread');
  12. const tenderConst = require('../const/tender');
  13. const measureType = tenderConst.measureType;
  14. const path = require('path');
  15. module.exports = app => {
  16. class StageController 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.showTender = true;
  27. ctx.showTitle = true;
  28. }
  29. /**
  30. * 获取通用的renderData(用于layout, Menu, subMenu部分)
  31. * @param ctx
  32. * @returns {{tender, tenderMenu, auditConst}}
  33. * @private
  34. */
  35. _getDefaultRenderData (ctx) {
  36. const data = {
  37. tender: ctx.tender.data,
  38. tenderMenu: JSON.parse(JSON.stringify(this.menu.stageMenu)),
  39. auditConst: auditConst.flow,
  40. measureType,
  41. preUrl: '/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order,
  42. stage: ctx.stage,
  43. };
  44. data.tenderMenu.back.children[0].url = '/tender/' + ctx.tender.id + '/measure/stage';
  45. return data;
  46. }
  47. _stageReadOnly(stage) {
  48. return stage.status === auditConst.flow.status.checked;
  49. }
  50. /**
  51. * 获取SpreadSetting
  52. * @private
  53. */
  54. _getSpreadSetting() {
  55. const _ = this.app._;
  56. function removeFieldCols(setting, cols) {
  57. _.remove(setting.cols, function (c) {
  58. return cols.indexOf(c.field) > -1;
  59. });
  60. }
  61. function setColFormat(cols, field, formatter) {
  62. const filterCols = cols.filter(function (c) {
  63. return c.field.search(field) !== -1;
  64. });
  65. for (const col of filterCols) {
  66. col.formatter = formatter;
  67. }
  68. }
  69. const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp);
  70. const upFormatter = this.ctx.helper.getNumberFormatter(2);
  71. const ledger = JSON.parse(JSON.stringify(spreadConst.stage.ledger));
  72. setColFormat(ledger.cols, 'unit_price', upFormatter);
  73. setColFormat(ledger.cols, 'total_price', tpFormatter);
  74. setColFormat(ledger.cols, 'tp', tpFormatter);
  75. const pos = JSON.parse(JSON.stringify(spreadConst.stage.pos));
  76. const tender = this.ctx.tender, stage = this.ctx.stage;
  77. if (this._stageReadOnly(stage)) {
  78. ledger.readOnly = true;
  79. pos.readOnly = true;
  80. }
  81. if (tender.data.measure_type === measureType.tz.value) {
  82. removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
  83. removeFieldCols(pos, spreadConst.filterCols.posTzWithoutCols);
  84. }
  85. if (!tender.info.display.ledger.dgnQty) {
  86. removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
  87. }
  88. return [ledger, pos];
  89. }
  90. /**
  91. * 获取期数据
  92. * @param ctx
  93. * @returns {Promise<void>}
  94. * @private
  95. */
  96. async _getStage(ctx) {
  97. const stageOrder = parseInt(ctx.params.order);
  98. ctx.stage = await ctx.service.stage.getDataByCondition({
  99. tid: ctx.tender.id,
  100. order: stageOrder,
  101. });
  102. ctx.stage.auditors = await ctx.service.stageAudit.getAuditors(ctx.stage.id, ctx.stage.times);
  103. ctx.stage.curAuditor = await ctx.service.stageAudit.getCurAuditor(ctx.stage.id, ctx.stage.times);
  104. }
  105. /**
  106. * 期计量页面 (Get)
  107. * @param {Object} ctx - egg全局变量
  108. * @returns {Promise<void>}
  109. */
  110. async index(ctx) {
  111. try {
  112. await this._getStage(ctx);
  113. const renderData = this._getDefaultRenderData(ctx);
  114. [renderData.ledgerSpread, renderData.posSpread] = this._getSpreadSetting();
  115. renderData.ledgerData = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
  116. renderData.curStageData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0);
  117. renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index);
  118. // 查询截止上期数据
  119. //if (ctx.stage.order > 0) {
  120. //renderData.preStageData
  121. //}
  122. await this.layout('stage/index.ejs', renderData, 'stage/modal.ejs');
  123. } catch (err) {
  124. this.log(err);
  125. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
  126. }
  127. }
  128. /**
  129. * 获取期数据(截止上期 & 本期)
  130. * @param ctx
  131. * @returns {Promise<void>}
  132. */
  133. async getStagePosData(ctx) {
  134. try {
  135. await this._getStage(ctx);
  136. const condition = JSON.parse(ctx.request.body.data) || {};
  137. condition.tid = ctx.tender.id;
  138. const responseData = {err: 0, msg: '', data: {}};
  139. responseData.data.pos = await ctx.service.pos.getPosData(condition);
  140. // todo 根据当前人,或指定对象查询数据
  141. responseData.data.curStageData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
  142. ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0,
  143. this.app._.map(responseData.data.pos, 'id'));
  144. ctx.body = responseData;
  145. } catch (err) {
  146. this.log(err);
  147. ctx.body = {err: 1, msg: err.toString(), data: null};
  148. }
  149. }
  150. /**
  151. * 保存数据
  152. * @param ctx
  153. * @returns {Promise<void>}
  154. */
  155. async updateStageData(ctx) {
  156. try {
  157. await this._getStage(ctx);
  158. // 检查登录用户,是否可操作
  159. if (ctx.session.sessionUser.accountId === ctx.stage.user_id) {
  160. if (ctx.stage.status === auditConst.flow.status.checking || ctx.stage.status === auditConst.flow.status.checked) {
  161. throw '该计量期当前您无权操作';
  162. }
  163. } else {
  164. // 检查是否可修改
  165. //const curAuditor = await ctx.service.stageAudit.get
  166. }
  167. const data = JSON.parse(ctx.request.body.data);
  168. const responseData = { err: 0, msg: '', data: {}, };
  169. if (data.pos) {
  170. responseData.data = await ctx.service.stagePos.updateStageData(data.pos);
  171. } else if (data.bills) {
  172. responseData.data.bills = await ctx.service.stageBills.updateStageData(data.bills);
  173. }
  174. ctx.body = responseData;
  175. } catch (err) {
  176. this.log(err);
  177. ctx.body = {err: 1, msg: err.toString(), data: null};
  178. }
  179. }
  180. /**
  181. * 中间计量
  182. * @param ctx
  183. * @returns {Promise<void>}
  184. */
  185. async detail(ctx) {
  186. try {
  187. await this._getStage(ctx);
  188. const renderData = this._getDefaultRenderData(ctx);
  189. renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.detail);
  190. renderData.imType = tenderConst.imType;
  191. await this.layout('stage/detail.ejs', renderData, 'stage/detail_modal.ejs');
  192. } catch (err) {
  193. this.log(err);
  194. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order);
  195. }
  196. }
  197. /**
  198. * 设置中间计量生成规则,并生成中间计量数据
  199. * @param ctx
  200. * @returns {Promise<void>}
  201. */
  202. async buildDetailData (ctx) {
  203. try {
  204. await this._getStage(ctx);
  205. // 检查登录用户,是否可操作
  206. if (ctx.session.sessionUser.accountId === ctx.stage.user_id) {
  207. if (ctx.stage.status === auditConst.flow.status.checking || ctx.stage.status === auditConst.flow.status.checked) {
  208. throw '该计量期当前您无权操作';
  209. }
  210. }
  211. const data = JSON.parse(ctx.request.body.data);
  212. await ctx.service.stage.buildDetailData(ctx.tender.id, ctx.stage.order, data);
  213. ctx.body = {err: 0, msg: '', data: null};
  214. } catch (err) {
  215. this.log(err);
  216. ctx.body = {err: 1, msg: err.toString(), data: null};
  217. }
  218. }
  219. /**
  220. * 加载数据
  221. * @param ctx
  222. * @returns {Promise<void>}
  223. */
  224. async loadDetailRelaData(ctx) {
  225. try {
  226. await this._getStage(ctx);
  227. const data = JSON.parse(ctx.request.body.data);
  228. // 加载台账数据
  229. if (data.loadType === 'ledger') {
  230. const ledgerData = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
  231. ctx.body = {err: 0, msg: '', data: ledgerData };
  232. } else if (data.loadType === 'all') {
  233. const ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
  234. const curStage = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id);
  235. const stageDetail = await ctx.service.stageDetail.getLastestStageData(ctx.tender.id, ctx.stage.id);
  236. ctx.body = {
  237. err: 0,
  238. msg: '',
  239. data: {
  240. ledger,
  241. curStage,
  242. stageDetail,
  243. }
  244. };
  245. }
  246. } catch (err) {
  247. this.log(err);
  248. ctx.body = {err: 1, msg: err.toString(), data: null};
  249. }
  250. }
  251. /**
  252. * 中间计量,生成规则,高级设置
  253. * @param ctx
  254. * @returns {Promise<void>}
  255. */
  256. async setAdvancedConfig(ctx) {
  257. try {
  258. await this._getStage(ctx);
  259. // 检查登录用户,是否可操作
  260. if (ctx.session.sessionUser.accountId === ctx.stage.user_id) {
  261. if (ctx.stage.status === auditConst.flow.status.checking || ctx.stage.status === auditConst.flow.status.checked) {
  262. throw '该计量期当前您无权操作';
  263. }
  264. }
  265. const data = JSON.parse(ctx.request.body.data);
  266. await ctx.service.stage.update(data, { id: ctx.stage.id });
  267. ctx.body = {err: 0, msg: '', data: this.ctx.stage};
  268. } catch (err) {
  269. this.log(err);
  270. ctx.body = {err: 1, msg: err.toString(), data: null};
  271. }
  272. }
  273. /**
  274. * 中间计量,编辑中间计量数据
  275. * @param ctx
  276. * @returns {Promise<void>}
  277. */
  278. async saveDetailData(ctx) {
  279. try {
  280. await this._getStage(ctx);
  281. // 检查登录用户,是否可操作
  282. if (ctx.session.sessionUser.accountId === ctx.stage.user_id) {
  283. if (ctx.stage.status === auditConst.flow.status.checking || ctx.stage.status === auditConst.flow.status.checked) {
  284. throw '该计量期当前您无权操作';
  285. }
  286. } else {
  287. // 检查是否可修改
  288. //const curAuditor = await ctx.service.stageAudit.get
  289. }
  290. const data = JSON.parse(ctx.request.body.data);
  291. const responseData = { err: 0, msg: '', data: {}, };
  292. responseData.data = await ctx.service.stageDetail.saveDetailData(data);
  293. ctx.body = responseData;
  294. } catch (err) {
  295. this.log(err);
  296. ctx.body = {err: 1, msg: err.toString(), data: null};
  297. }
  298. }
  299. /**
  300. * 中间计量,添加草图,上传图片
  301. * @param ctx
  302. * @returns {Promise<void>}
  303. */
  304. async addCalcImage(ctx) {
  305. try {
  306. const stream = await ctx.getFileStream();
  307. const create_time = Date.parse(new Date()) / 1000;
  308. const fileInfo = path.parse(stream.filename);
  309. const fileName = path.join('public/upload', this.ctx.tender.id.toString(), 'im', 'calcImg_' + create_time + fileInfo.ext);
  310. await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', fileName));
  311. ctx.body = {err: 0, msg: '', data: fileName};
  312. } catch(err) {
  313. this.log(err);
  314. ctx.body = {err: 1, msg: err.toString(), data: null};
  315. }
  316. }
  317. /**
  318. * 中间计量,设置草图
  319. * @param ctx
  320. * @returns {Promise<void>}
  321. */
  322. async mergeCalcImage(ctx) {
  323. try {
  324. await this._getStage(ctx);
  325. // 检查登录用户,是否可操作
  326. if (ctx.session.sessionUser.accountId === ctx.stage.user_id) {
  327. if (ctx.stage.status === auditConst.flow.status.checking || ctx.stage.status === auditConst.flow.status.checked) {
  328. throw '该计量期当前您无权操作';
  329. }
  330. } else {
  331. // 检查是否可修改
  332. //const curAuditor = await ctx.service.stageAudit.get
  333. }
  334. const data = JSON.parse(ctx.request.body.data);
  335. if (data.updateType === 'update') {
  336. const create_time = Date.parse(new Date()) / 1000;
  337. const fileName = path.join('public/upload', this.ctx.tender.id.toString(), 'im', 'calcImg_' + create_time + '.jpg');
  338. const base64Data = data.img.replace(/^data:image\/\w+;base64,/, "");
  339. const dataBuffer = new Buffer(base64Data, 'base64');
  340. await this.ctx.helper.saveBufferFile(dataBuffer, path.join(this.app.baseDir, 'app', fileName));
  341. data.calc_img = fileName;
  342. data.calc_img_org = JSON.stringify(data.imgInfo);
  343. delete data.updateType;
  344. delete data.img;
  345. delete data.imgInfo;
  346. } else if (data.updateType === 'clear') {
  347. data.calc_img = null;
  348. data.calc_img_org = null;
  349. delete data.updateType;
  350. }
  351. await this.ctx.service.stageDetail.saveDetailData(data);
  352. const imData = await ctx.service.stageDetail.getLastestImStageData(this.ctx.tender.id, this.ctx.stage.id, data.lid, data.uuid);
  353. const responseData = {err: 0, msg: '', data: imData};
  354. ctx.body = responseData;
  355. } catch (err) {
  356. this.log(err);
  357. ctx.body = {err: 1, msg: err.toString(), data: null};
  358. }
  359. }
  360. /**
  361. * 合同支付
  362. * @param ctx
  363. * @returns {Promise<void>}
  364. */
  365. async pay(ctx) {
  366. try {
  367. await this._getStage(ctx);
  368. const renderData = this._getDefaultRenderData(ctx);
  369. await this.layout('stage/pay.ejs', renderData, 'stage/pay_modal.ejs');
  370. } catch (err) {
  371. this.log(err);
  372. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
  373. }
  374. }
  375. /**
  376. * 变更令
  377. * @param ctx
  378. * @returns {Promise<void>}
  379. */
  380. async change(ctx) {
  381. try {
  382. await this._getStage(ctx);
  383. const renderData = this._getDefaultRenderData(ctx);
  384. await this.layout('stage/change.ejs', renderData);
  385. } catch (err) {
  386. this.log(err);
  387. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
  388. }
  389. }
  390. // 审批相关
  391. /**
  392. * 添加审批人
  393. * @param ctx
  394. * @returns {Promise<void>}
  395. */
  396. async addAudit(ctx) {
  397. try {
  398. await this._getStage(ctx);
  399. const data = JSON.parse(ctx.request.body.data);
  400. const id = data.auditorId;
  401. if (isNaN(id) || id <= 0) {
  402. throw '参数错误';
  403. }
  404. const result = await ctx.service.stageAudit.addAuditor(ctx.stage.id, id);
  405. if (!result) {
  406. throw '添加审核人失败';
  407. }
  408. const audit = await ctx.service.stageAudit.getAuditor(ctx.stage.id, id);
  409. ctx.body = {err: 0, msg: '', data: audit};
  410. } catch (err) {
  411. this.log(err);
  412. ctx.body = {err: 1, msg: err.toString(), data: null};
  413. }
  414. }
  415. /**
  416. * 移除审批人
  417. * @param ctx
  418. * @returns {Promise<void>}
  419. */
  420. async deleteAudit(ctx) {
  421. try {
  422. await this._getStage(ctx);
  423. const data = JSON.parse(ctx.request.body.data);
  424. const id = data.auditorId instanceof Number ? data.auditorId : this.app._.toNumber(data.auditorId);
  425. if (isNaN(id) || id <= 0) {
  426. throw '参数错误';
  427. }
  428. const result = await ctx.service.stageAudit.deleteAuditor(ctx.stage.id, id, ctx.stage.times);
  429. if (!result) {
  430. throw '移除审核人失败';
  431. }
  432. const auditors = await ctx.service.stageAudit.getAuditors(ctx.stage.id);
  433. ctx.body = {err: 0, msg: '', data: auditors};
  434. } catch (err) {
  435. ctx.body = {err: 1, msg: err.toString(), data: null};
  436. }
  437. }
  438. /**
  439. * 上报
  440. * @param ctx
  441. * @returns {Promise<void>}
  442. */
  443. async startAudit(ctx) {
  444. }
  445. /**
  446. * 审批
  447. * @param ctx
  448. * @returns {Promise<void>}
  449. */
  450. async checkAudit(ctx) {
  451. }
  452. _getGatherSpreadSetting() {
  453. const _ = this.app._;
  454. function removeFieldCols(setting, cols) {
  455. _.remove(setting.cols, function (c) {
  456. return cols.indexOf(c.field) > -1;
  457. });
  458. }
  459. function setColFormat(cols, field, formatter) {
  460. const filterCols = cols.filter(function (c) {
  461. return c.field.search(field) !== -1;
  462. });
  463. for (const col of filterCols) {
  464. col.formatter = formatter;
  465. }
  466. }
  467. const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp);
  468. const upFormatter = this.ctx.helper.getNumberFormatter(2);
  469. const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl));
  470. setColFormat(gcl.cols, 'unit_price', upFormatter);
  471. setColFormat(gcl.cols, 'total_price', tpFormatter);
  472. setColFormat(gcl.cols, 'tp', tpFormatter);
  473. const leafXmj = JSON.parse(JSON.stringify(spreadConst.stageGather.leafXmj));
  474. const tender = this.ctx.tender;
  475. if (tender.data.measure_type === measureType.tz.value) {
  476. removeFieldCols(gcl, spreadConst.filterCols.tzWithoutCols);
  477. }
  478. return [gcl, leafXmj];
  479. }
  480. /**
  481. * 清单汇总
  482. * @param ctx
  483. * @returns {Promise<void>}
  484. */
  485. async gather(ctx) {
  486. try {
  487. await this._getStage(ctx);
  488. const renderData = this._getDefaultRenderData(ctx);
  489. [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting();
  490. renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
  491. renderData.curLedgerData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0);
  492. renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id});
  493. // todo 根据当前人,或指定对象查询数据
  494. renderData.curPosData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
  495. ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0);
  496. //renderData.gcl = await this.ctx.service.ledger.getAllLeafGclBills(this.ctx.tender.id);
  497. renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.gather);
  498. await this.layout('stage/gather.ejs', renderData);
  499. } catch (err) {
  500. this.log(err);
  501. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order);
  502. }
  503. }
  504. /**
  505. * 审核比较
  506. * @param ctx
  507. * @returns {Promise<void>}
  508. */
  509. async compare(ctx) {
  510. function getCompareSpreadSetting () {
  511. function setColFormat(cols, field, formatter) {
  512. const filterCols = cols.filter(function (c) {
  513. return c.field.search(field) !== -1;
  514. });
  515. for (const col of filterCols) {
  516. col.formatter = formatter;
  517. }
  518. }
  519. const tpFormatter = ctx.helper.getNumberFormatter(ctx.tender.info.decimal.tp);
  520. const upFormatter = ctx.helper.getNumberFormatter(2);
  521. const ledger = JSON.parse(JSON.stringify(spreadConst.stageCompare.ledger));
  522. setColFormat(ledger.baseCols, 'unit_price', upFormatter);
  523. setColFormat(ledger.extraCols, 'total_price', tpFormatter);
  524. setColFormat(ledger.extraCols, 'tp', tpFormatter);
  525. const pos = JSON.parse(JSON.stringify(spreadConst.stageCompare.pos));
  526. return [ledger, pos];
  527. };
  528. try {
  529. await this._getStage(ctx);
  530. const renderData = this._getDefaultRenderData(ctx);
  531. [renderData.ledgerSpread, renderData.posSpread] = getCompareSpreadSetting();
  532. renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
  533. renderData.orgStageLedger = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0);
  534. renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id});
  535. renderData.orgStagePos = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
  536. ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0);
  537. renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.compare);
  538. await this.layout('stage/compare.ejs', renderData, 'stage/compare_modal.ejs');
  539. } catch (err) {
  540. this.log(err);
  541. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order);
  542. }
  543. }
  544. async compareAuditor(ctx) {
  545. try {
  546. await this._getStage(ctx);
  547. const data = JSON.parse(ctx.request.body.data);
  548. const result = [];
  549. for (const order of data.auditors) {
  550. const data = { order: order, bills: [], pos: [] };
  551. data.bills = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, order);
  552. data.pos = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, order);
  553. result.push(data);
  554. }
  555. ctx.body = {err: 0, msg: '', data: result};
  556. } catch (err) {
  557. this.log(err);
  558. ctx.body = {err: 1, msg: err.toString(), data: null};
  559. }
  560. }
  561. /**
  562. * 报表
  563. * @param ctx
  564. * @returns {Promise<void>}
  565. */
  566. async report(ctx) {
  567. try {
  568. await this._getStage(ctx);
  569. const renderData = this._getDefaultRenderData(ctx);
  570. await this.layout('stage/report.ejs', renderData, 'stage/report_modal.ejs');
  571. } catch (err) {
  572. this.log(err);
  573. ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
  574. }
  575. }
  576. }
  577. return StageController;
  578. };