'use strict'; /** * * * @author Mai * @date 2018/6/20 * @version */ const moment = require('moment'); const auditConst = require('../const/audit').stage; const changeAudit = require('../const/audit').flow; const spreadConst = require('../const/spread'); const tenderConst = require('../const/tender'); const payConst = require('../const/deal_pay.js'); const changeConst = require('../const/change'); const measureType = tenderConst.measureType; const path = require('path'); const PayCalculator = require('../lib/pay_calc'); const accountGroup = require('../const/account_group').group; module.exports = app => { class StageController extends app.BaseController { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); ctx.showProject = true; ctx.showTender = true; ctx.showTitle = true; } /** * 获取通用的renderData(用于layout, Menu, subMenu部分) * @param ctx * @returns {{tender, tenderMenu, auditConst}} * @private */ async _getDefaultRenderData (ctx) { const data = { tender: ctx.tender.data, tenderMenu: JSON.parse(JSON.stringify(this.menu.stageMenu)), auditConst, measureType, preUrl: '/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order, stage: ctx.stage, }; if ((ctx.stage.status === auditConst.status.uncheck || ctx.stage.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === ctx.stage.user_id) { data.accountGroup = accountGroup; // 获取所有项目参与者 const accountList = await ctx.service.projectAccount.getAllDataByCondition({ where: { project_id: ctx.session.sessionProject.id, enable: 1 }, columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group'], }); data.accountList = accountList; } data.tenderMenu.back.children[0].url = '/tender/' + ctx.tender.id + '/measure/stage'; return data; } _stageReadOnly(stage) { return stage.status === auditConst.status.checked; } /** * 获取SpreadSetting * @private */ _getSpreadSetting() { const _ = this.app._; function removeFieldCols(setting, cols) { _.remove(setting.cols, function (c) { return cols.indexOf(c.field) > -1; }); } function setColFormat(cols, field, formatter) { const filterCols = cols.filter(function (c) { return c.field.search(field) !== -1; }); for (const col of filterCols) { col.formatter = formatter; } } // const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp); // const upFormatter = this.ctx.helper.getNumberFormatter(2); const ledger = JSON.parse(JSON.stringify(spreadConst.stage.ledger)); // setColFormat(ledger.cols, 'unit_price', upFormatter); // setColFormat(ledger.cols, 'total_price', tpFormatter); // setColFormat(ledger.cols, 'tp', tpFormatter); const pos = JSON.parse(JSON.stringify(spreadConst.stage.pos)); const tender = this.ctx.tender, stage = this.ctx.stage; if (this._stageReadOnly(stage)) { ledger.readOnly = true; pos.readOnly = true; } if (tender.data.measure_type === measureType.tz.value) { removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols); removeFieldCols(pos, spreadConst.filterCols.posTzWithoutCols); } if (!tender.info.display.ledger.dgnQty) { removeFieldCols(ledger, spreadConst.filterCols.dgnCols); } if (this.ctx.stage.readOnly) { ledger.readOnly = true; pos.readOnly = true; } return [ledger, pos]; } /** * 获取审批界面所需的 原报、审批人数据等 * @param ctx * @returns {Promise} * @private */ async _getStageAuditViewData (ctx) { const times = ctx.stage.status === auditConst.status.checkNo ? ctx.stage.times - 1 : ctx.stage.times; ctx.stage.user = await ctx.service.projectAccount.getAccountInfoById(ctx.stage.user_id); ctx.stage.auditHistory = []; if (ctx.stage.times > 1) { for (let i = 1; i < ctx.stage.times; i++) { ctx.stage.auditHistory.push(await ctx.service.stageAudit.getAuditors(ctx.stage.id, i)); } } // 获取审批流程中左边列表 ctx.stage.auditors2 = await ctx.service.stageAudit.getAuditGroupByList(ctx.stage.id, times); if (ctx.stage.status === auditConst.status.uncheck || ctx.stage.status === auditConst.status.checkNo) { ctx.stage.auditorList = await ctx.service.stageAudit.getAuditors(ctx.stage.id, ctx.stage.times); } } /** * 期计量页面 (Get) * @param {Object} ctx - egg全局变量 * @returns {Promise} */ async index(ctx) { try { await this._getStageAuditViewData(ctx); const renderData = await this._getDefaultRenderData(ctx); [renderData.ledgerSpread, renderData.posSpread] = this._getSpreadSetting(); renderData.changeConst = changeConst; renderData.ledgerData = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); // 当前操作人查看最新数据,其他人查看历史数据 if (ctx.stage.readOnly) { renderData.curStageData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder); } else { renderData.curStageData = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id); } renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index); // 查询截止上期数据 if (ctx.stage.order > 1) { renderData.preStageData = await ctx.service.stageBillsFinal.getFinalData(ctx.tender.data, ctx.stage); } else { renderData.preStageData = []; } await this.layout('stage/index.ejs', renderData, 'stage/modal.ejs'); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage'); } } /** * 获取期数据(截止上期 & 本期) (Ajax) * @param ctx * @returns {Promise} */ async getStagePosData(ctx) { try { const condition = JSON.parse(ctx.request.body.data) || {}; condition.tid = ctx.tender.id; const responseData = {err: 0, msg: '', data: {}}; responseData.data.pos = await ctx.service.pos.getPosData(condition); // 根据当前人,或指定对象查询数据 if (ctx.stage.readOnly) { responseData.data.curStageData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder, this.app._.map(responseData.data.pos, 'id')); } else { responseData.data.curStageData = await ctx.service.stagePos.getLastestStageData(ctx.tender.id, ctx.stage.id, this.app._.map(responseData.data.pos, 'id')); } // 查询截止上期数据 if (ctx.stage.order > 1) { responseData.data.preStageData = await ctx.service.stagePosFinal.getFinalData(ctx.tender.data, ctx.stage); } else { responseData.data.preStageData = []; } ctx.body = responseData; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 保存数据 (Ajax) * @param ctx * @returns {Promise} */ async updateStageData(ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); const responseData = { err: 0, msg: '', data: {}, }; if (data.pos) { responseData.data = await ctx.service.stagePos.updateStageData(data.pos); } else if (data.bills) { responseData.data.bills = await ctx.service.stageBills.updateStageData(data.bills); } ctx.body = responseData; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 中间计量 (Get) * @param ctx * @returns {Promise} */ async detail(ctx) { try { await this._getStageAuditViewData(ctx); const renderData = await this._getDefaultRenderData(ctx); renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.detail); renderData.imType = tenderConst.imType; await this.layout('stage/detail.ejs', renderData, 'stage/detail_modal.ejs'); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order); } } /** * 设置中间计量生成规则,并生成中间计量数据 (Ajax) * @param ctx * @returns {Promise} */ async buildDetailData (ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); await ctx.service.stage.buildDetailData(ctx.tender.id, ctx.stage.order, data); ctx.body = {err: 0, msg: '', data: null}; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 加载数据 (Ajax) * @param ctx * @returns {Promise} */ async loadDetailRelaData(ctx) { try { const data = JSON.parse(ctx.request.body.data); // 加载台账数据 if (data.loadType === 'ledger') { const ledgerData = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); ctx.body = {err: 0, msg: '', data: ledgerData }; } else if (data.loadType === 'all') { const result = {}; result.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); result.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id}); if (ctx.stage.readOnly) { result.curStage = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder); result.curPosStage = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder); result.stageDetail = await ctx.service.stageDetail.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder); } else { result.curStage = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id); result.curPosStage = await ctx.service.stagePos.getLastestStageData(ctx.tender.id, ctx.stage.id); result.stageDetail = await ctx.service.stageDetail.getLastestStageData(ctx.tender.id, ctx.stage.id); } ctx.body = { err: 0, msg: '', data: result }; } } catch (err) { this.log(err); ctx.body = { err: 1, msg: err.toString(), data: null }; } } /** * 中间计量,生成规则,高级设置 (Ajax) * @param ctx * @returns {Promise} */ async setAdvancedConfig(ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); await ctx.service.stage.update(data, { id: ctx.stage.id }); ctx.body = {err: 0, msg: '', data: this.ctx.stage}; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 中间计量,编辑中间计量数据(Ajax) * @param ctx * @returns {Promise} */ async saveDetailData(ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); const responseData = { err: 0, msg: '', data: {}, }; responseData.data = await ctx.service.stageDetail.saveDetailData(data); ctx.body = responseData; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 中间计量,添加草图,上传图片 (Ajax) * @param ctx * @returns {Promise} */ async addCalcImage(ctx) { try { if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const stream = await ctx.getFileStream(); const create_time = Date.parse(new Date()) / 1000; const fileInfo = path.parse(stream.filename); const fileName = path.join('public/upload', this.ctx.tender.id.toString(), 'im', 'calcImg_' + create_time + fileInfo.ext); await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', fileName)); ctx.body = {err: 0, msg: '', data: fileName}; } catch(err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 中间计量,设置草图 (Ajax) * @param ctx * @returns {Promise} */ async mergeCalcImage(ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); if (data.updateType === 'update') { const create_time = Date.parse(new Date()) / 1000; const fileName = path.join('public/upload', this.ctx.tender.id.toString(), 'im', 'calcImg_' + create_time + '.jpg'); const base64Data = data.img.replace(/^data:image\/\w+;base64,/, ""); const dataBuffer = new Buffer(base64Data, 'base64'); await this.ctx.helper.saveBufferFile(dataBuffer, path.join(this.app.baseDir, 'app', fileName)); data.calc_img = fileName; data.calc_img_org = JSON.stringify(data.imgInfo); delete data.updateType; delete data.img; delete data.imgInfo; } else if (data.updateType === 'clear') { data.calc_img = null; data.calc_img_org = null; delete data.updateType; } await this.ctx.service.stageDetail.saveDetailData(data); const imData = await ctx.service.stageDetail.getLastestImStageData(this.ctx.tender.id, this.ctx.stage.id, data.lid, data.uuid); const responseData = {err: 0, msg: '', data: imData}; ctx.body = responseData; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 合同支付 (Get) * @param ctx * @returns {Promise} */ async pay(ctx) { try { await this._getStageAuditViewData(ctx); const renderData = await this._getDefaultRenderData(ctx); renderData.dealPay = await ctx.service.stagePay.getStagePays(ctx.stage); // if (dealPay && dealPay.length > 0) { // renderData.dealPay = dealPay; // } else { // await ctx.service.pay.addDefaultPayData(this.ctx.tender.id); // await ctx.service.stagePay.addInitialStageData(ctx.stage); // renderData.dealPay = await ctx.service.stagePay.getStagePays(ctx.stage); // } renderData.calcBase = await ctx.service.stage.getStagePayCalcBase(); renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.pay); // 计算 本期金额 const payCalculator = new PayCalculator(this.ctx, this.ctx.tender.info.decimal); await payCalculator.calculateAll(renderData.dealPay); await this.layout('stage/pay.ejs', renderData, 'stage/pay_modal.ejs'); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage'); } } /** * 合同支付 - 编辑合同支付项 (Ajax) * @param ctx * @returns {Promise} */ async savePayData(ctx) { try { // 检查登录用户,是否可操作 if (ctx.stage.readOnly) { throw '该计量期当前您无权操作'; } const data = JSON.parse(ctx.request.body.data); const responseData = { err: 0, msg: '', data: {}, }; const payCalculator = new PayCalculator(this.ctx, this.ctx.tender.info.decimal); switch (data.type) { case 'add': responseData.data = await ctx.service.pay.add(); responseData.data = await ctx.service.stagePay.getStagePay(ctx.stage, responseData.data.pid); break; case 'del': await ctx.service.pay.del(data.id); responseData.data = await ctx.service.stagePay.getStagePays(ctx.stage); await payCalculator.calculate(responseData.data); break; case 'changeOrder': responseData.data = await ctx.service.pay.changeOrder(data.id1, data.id2); break; case 'info': responseData.data = await ctx.service.pay.save(data.updateData); if (data.updateData.sexpr !== undefined || data.updateData.sprice !== undefined || data.updateData.rexpr !== undefined || data.updateData.rprice !== undefined || data.updateData.minus !== undefined || data.updateData.is_yf !== undefined || data.updateData.dl_type !== undefined) { responseData.data = await ctx.service.stagePay.getStagePays(ctx.stage); await payCalculator.calculateAll(responseData.data); //console.log(responseData.data[responseData.data.length - 1]); } else { responseData.data = await ctx.service.stagePay.getStagePay(ctx.stage, responseData.data.id); } break; case 'stage': await ctx.service.stagePay.save(data.updateData); responseData.data = await ctx.service.stagePay.getStagePays(ctx.stage); await payCalculator.calculateAll(responseData.data); break; } ctx.body = responseData; } catch(err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 合同支付 - 章节明细 (Ajax-Post) * @param ctx * @returns {Promise} */ async chapterDetail(ctx) { const _ = this.app._; const fields = ['contract_tp', 'qc_tp', 'gather_tp', 'end_gather_tp']; function assignStageData(chapter, curStage, preStage) { chapter.contract_tp = curStage.contract_tp; chapter.qc_tp = curStage.qc_tp; chapter.gather_tp = ctx.helper.plus(curStage.contract_tp, curStage.qc_tp); if (preStage) { chapter.pre_contract_tp = preStage.contract_tp; chapter.pre_qc_tp = preStage.qc_tp; chapter.pre_gather_tp = ctx.helper.plus(preStage.contract_tp, preStage.qc_tp); chapter.end_contract_tp = ctx.helper.plus(curStage.contract_tp, preStage.contract_tp); chapter.end_qc_tp = ctx.helper.plus(curStage.qc_tp, preStage.qc_tp); chapter.end_gather_tp = ctx.helper.plus(chapter.gather_tp, chapter.pre_gather_tp); } else { chapter.end_contract_tp = curStage.contract_tp; chapter.end_qc_tp = curStage.qc_tp; chapter.end_gather_tp = chapter.gather_tp; } } try { const chapterDetail = JSON.parse(JSON.stringify(payConst.chapterDetail)); const calcDetail = _.sortBy(chapterDetail, ['cType']); for (const cd of calcDetail) { switch (cd.cType) { case 1: const tp = await ctx.service.stageBills.getSumTotalPriceGcl(ctx.stage, cd.filter); assignStageData(cd, tp); break; case 11: assignStageData(cd, await ctx.service.stageBills.getSumTotalPriceGcl(ctx.stage)); break; case 21: const sum = _.find(calcDetail, {cType: 11}); const chapters = _.filter(calcDetail, {cType: 1}); for (const f of fields) { cd[f] = ctx.helper.minus(sum[f], this.ctx.helper.sum(_.map(chapters, f)));//_.sumBy(chapters, f)); } break; case 31: assignStageData(cd, await ctx.service.stageBills.getSumTotalPriceNotGcl(ctx.stage)); break; case 41: const sum1 = _.find(calcDetail, {cType: 11}); const sum2 = _.find(calcDetail, {cType: 31}); for (const f of fields) { cd[f] = ctx.helper.plus(sum1.value, sum2.value); } break; } } ctx.body = {err: 0, msg: '', data: {detail: chapterDetail, decimal: ctx.tender.info.decimal}}; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } // 变更令相关 /** * 查询变更令 明细数据(包括附件、变更清单、累计使用情况、本期使用情况) * @param tid * @param sid * @param cid * @returns {Promise<{}>} * @private */ async _getChangeDetailData(tid, sid, cid) { const data = {}; data.attachments = await this.ctx.service.changeAtt.getChangeAttachment(cid); data.addUsedBills = await this.ctx.service.stageChange.getUsedData(tid, cid); data.curUsedBills = await this.ctx.service.stageChange.getStageUsedData(sid, cid); return data; } /** * 变更令 (Get) * @param ctx * @returns {Promise} */ async change(ctx) { try { const renderData = await this._getDefaultRenderData(ctx); renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); renderData.changes = await ctx.service.change.getChangeAndUsedInfo(ctx.tender.id); if (renderData.changes.length > 0) { const change = renderData.changes[0]; change.detail = await this._getChangeDetailData(ctx.tender.id, ctx.stage.id, change.cid); } renderData.usedChangesId = await ctx.service.stageChange.getStageUsedChangeId(ctx.stage.id); renderData.changeConst = changeConst; renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.change); await this.layout('stage/change.ejs', renderData); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage'); } } /** * 查询可用变更令 (Ajax-Post) * @param ctx * @returns {Promise} */ async searchValidChange(ctx) { try { // if (ctx.stage.readOnly) { // throw '您无权调用变更令'; // } const data = JSON.parse(ctx.request.body.data); if (!data.bills && !data.pos) { throw '数据错误'; } const bills = data.bills ? data.bills : await ctx.service.ledger.getDataById(data.pos.lid); const pos = data.pos; const changes = await ctx.service.change.getValidChanges(ctx.tender.id, bills, pos); const useChanges = await ctx.service.stageChange.getLastestStageData(ctx.tender.id, ctx.stage.id, bills.id, pos ? pos.id : -1); ctx.body = {err: 0, msg: '', data: {changes, useChanges}}; } catch(err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 调用变更令 (Ajax-Post) * @param ctx * @returns {Promise} */ async useChange(ctx) { try { if (ctx.stage.readOnly) { throw '您无权使用变更令'; } const data = JSON.parse(ctx.request.body.data); if (!data.target || (!data.target.bills && !data.target.pos) || !data.change) { throw '调用变更令数据错误' } let result; if (data.target.bills) { result = await ctx.service.stageChange.billsChange(data.target.bills, data.change); } else { result = await ctx.service.stageChange.posChange(data.target.pos, data.change); } ctx.body = {err: 0, msg: '', data: result}; } catch(err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 查询变更令 明细数据(包括附件、变更清单、累计使用情况、本期使用情况) (Ajax-Post) * @param ctx * @returns {Promise} */ async changeDetail(ctx) { try { const data = JSON.parse(ctx.request.body.data); if (!data.cid) { throw '查询数据错误'; } const detailData = await this._getChangeDetailData(ctx.tender.id, ctx.stage.id, data.cid); ctx.body = {err: 0, msg: '', data: detailData}; } catch(err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } // 审批相关 /** * 添加审批人 * @param ctx * @returns {Promise} */ async addAudit(ctx) { try { const data = JSON.parse(ctx.request.body.data); const id = this.app._.toInteger(data.auditorId); if (isNaN(id) || id <= 0) { throw '参数错误'; } // 检查权限等 if (ctx.stage.user_id !== ctx.session.sessionUser.accountId) { throw '您无权添加审核人'; } if (ctx.stage.status === auditConst.status.checking || ctx.stage.status === auditConst.status.checked) { throw '当前不允许添加审核人'; } // 检查审核人是否已存在 const exist = this.app._.find(ctx.stage.auditorList, {aid: id}); if (exist) { throw '该审核人已存在,请勿重复添加'; } const result = await ctx.service.stageAudit.addAuditor(ctx.stage.id, id, ctx.stage.times); if (!result) { throw '添加审核人失败'; } const audit = await ctx.service.stageAudit.getAuditor(ctx.stage.id, id, ctx.stage.times); ctx.body = {err: 0, msg: '', data: audit}; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 移除审批人 * @param ctx * @returns {Promise} */ async deleteAudit(ctx) { try { const data = JSON.parse(ctx.request.body.data); const id = data.auditorId instanceof Number ? data.auditorId : this.app._.toNumber(data.auditorId); if (isNaN(id) || id <= 0) { throw '参数错误'; } const result = await ctx.service.stageAudit.deleteAuditor(ctx.stage.id, id, ctx.stage.times); if (!result) { throw '移除审核人失败'; } const auditors = await ctx.service.stageAudit.getAuditors(ctx.stage.id, ctx.stage.times); ctx.body = {err: 0, msg: '', data: auditors}; } catch (err) { ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 上报 * @param ctx * @returns {Promise} */ async startAudit(ctx) { try { // 检查权限等 if (!ctx.stage) { throw '数据错误'; } if (ctx.stage.user_id !== ctx.session.sessionUser.accountId) { throw '您无权上报该期数据'; } if (ctx.stage.status === auditConst.status.checking || ctx.stage.status === auditConst.status.checked) { throw '该期数据当前无法上报'; } await ctx.service.stageAudit.start(ctx.stage.id, ctx.stage.times); ctx.redirect(ctx.request.header.referer); } catch (err) { this.log(err); ctx.session.postError = err.toString(); ctx.redirect(ctx.request.header.referer); } } /** * 审批 * @param ctx * @returns {Promise} */ async checkAudit(ctx) { try { if (!this.ctx.stage || (this.ctx.stage.status !== auditConst.status.checking && this.ctx.stage.status !== auditConst.status.checkNoPre)) { throw '当前期数据有误'; } if (!this.ctx.stage.curAuditor || this.ctx.stage.curAuditor.aid !== ctx.session.sessionUser.accountId) { throw '您无权进行该操作'; } const data = { checkType: parseInt(ctx.request.body.checkType), opinion: ctx.request.body.opinion, }; if (!data.checkType || isNaN(data.checkType)) { throw '提交数据错误'; } if (data.checkType === auditConst.status.checkNo) { if (!data.checkType || isNaN(data.checkType)) { throw '提交数据错误'; } } await ctx.service.stageAudit.check(ctx.stage.id, data, ctx.stage.times); console.log('success'); ctx.redirect(ctx.request.header.referer); } catch (err) { console.log(err); this.log(err); ctx.session.postError = err.toString(); ctx.redirect(ctx.request.header.referer); } } // 清单汇总相关 _getGatherSpreadSetting() { const _ = this.app._; function removeFieldCols(setting, cols) { _.remove(setting.cols, function (c) { return cols.indexOf(c.field) > -1; }); } function setColFormat(cols, field, formatter) { const filterCols = cols.filter(function (c) { return c.field.search(field) !== -1; }); for (const col of filterCols) { col.formatter = formatter; } } const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp); const upFormatter = this.ctx.helper.getNumberFormatter(2); const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl)); setColFormat(gcl.cols, 'unit_price', upFormatter); setColFormat(gcl.cols, 'total_price', tpFormatter); setColFormat(gcl.cols, 'tp', tpFormatter); const leafXmj = JSON.parse(JSON.stringify(spreadConst.stageGather.leafXmj)); const tender = this.ctx.tender; if (tender.data.measure_type === measureType.tz.value) { removeFieldCols(gcl, spreadConst.filterCols.tzWithoutCols); } return [gcl, leafXmj]; } /** * 清单汇总 页面 (Get) * @param ctx * @returns {Promise} */ async gather(ctx) { try { const renderData = await this._getDefaultRenderData(ctx); [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting(); renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); renderData.curLedgerData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0); renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id}); // todo 根据当前人,或指定对象查询数据 renderData.curPosData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0); //renderData.gcl = await this.ctx.service.ledger.getAllLeafGclBills(this.ctx.tender.id); renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.gather); await this.layout('stage/gather.ejs', renderData); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order); } } /** * 审核比较 页面 (Get) * @param ctx * @returns {Promise} */ async compare(ctx) { function getCompareSpreadSetting () { function setColFormat(cols, field, formatter) { const filterCols = cols.filter(function (c) { return c.field.search(field) !== -1; }); for (const col of filterCols) { col.formatter = formatter; } } const tpFormatter = ctx.helper.getNumberFormatter(ctx.tender.info.decimal.tp); const upFormatter = ctx.helper.getNumberFormatter(2); const ledger = JSON.parse(JSON.stringify(spreadConst.stageCompare.ledger)); setColFormat(ledger.baseCols, 'unit_price', upFormatter); setColFormat(ledger.extraCols, 'total_price', tpFormatter); setColFormat(ledger.extraCols, 'tp', tpFormatter); const pos = JSON.parse(JSON.stringify(spreadConst.stageCompare.pos)); return [ledger, pos]; }; try { const renderData = await this._getDefaultRenderData(ctx); [renderData.ledgerSpread, renderData.posSpread] = getCompareSpreadSetting(); renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1); renderData.orgStageLedger = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0); renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id}); renderData.orgStagePos = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0); renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.compare); await this.layout('stage/compare.ejs', renderData, 'stage/compare_modal.ejs'); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage/' + ctx.params.order); } } async compareAuditor(ctx) { try { const data = JSON.parse(ctx.request.body.data); const result = []; for (const order of data.auditors) { const data = { order: order, bills: [], pos: [] }; data.bills = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, order); data.pos = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, order); result.push(data); } ctx.body = {err: 0, msg: '', data: result}; } catch (err) { this.log(err); ctx.body = {err: 1, msg: err.toString(), data: null}; } } /** * 报表 * @param ctx * @returns {Promise} */ async report(ctx) { try { const renderData = await this._getDefaultRenderData(ctx); await this.layout('stage/report.ejs', renderData, 'stage/report_modal.ejs'); } catch (err) { this.log(err); ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage'); } } } return StageController; };