'use strict'; /** * Created by Tony on 2019/7/5. */ const tenderMenu = require('../../config/menu').tenderMenu; const measureType = require('../const/tender').measureType; const JpcEx = require('../reports/rpt_component/jpc_ex'); const JV = require('../reports/rpt_component/jpc_value_define'); const rptDataExtractor = require('../reports/util/rpt_calculation_data_util'); const fsUtil = require('../public/js/fsUtil'); module.exports = app => { class ReportController extends app.BaseController { /** * 报表显示页面 * * @param {Object} ctx - egg全局context * @return {void} */ async index(ctx) { try { const tender = ctx.tender; const stage = ctx.stage; // console.log(tender.data); // console.log(tender.data.project_id); let stage_id = -1; let stage_order = -1; let stage_times = -1; let stage_status = -1; const treeNodes = await ctx.service.rptTreeNode.getNodesByProjectId([-1, tender.data.project_id]); const custCfg = await ctx.service.rptCustomizeCfg.getCustomizeCfgByUserId('Administrator'); const stageList = await ctx.service.stage.getValidStagesShort(tender.id); const prjAccList = await ctx.service.projectAccount.getAllAccountByProjectId(tender.data.project_id); // console.log(maxStageAmt[0].maxAmt); if (stage !== null && stage !== undefined) { stage_id = stage.id; stage_order = stage.order; stage_times = stage.times; stage_status = stage.status; } const renderData = { tender: tender.data, tenderInfo: tender.info, rpt_tpl_data: JSON.stringify(treeNodes), cust_cfg: JSON.stringify(custCfg), project_id: tender.data.project_id, tender_id: tender.id, stg_id: stage_id, stg_order: stage_order, stg_times: stage_times, stg_status: stage_status, stage_list: JSON.stringify(stageList), prj_account_list: JSON.stringify(prjAccList), tenderMenu, preUrl: '/tender/' + tender.id, measureType, // jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.ledger.explode), }; // await this.layout('report/index.ejs', renderData, 'ledger/audit_modal.ejs'); await this.layout('report/index.ejs', renderData, 'report/rpt_all_popup.ejs'); } catch (err) { this.log(err); console.log(err); // ctx.redirect('/tender/' + ctx.tender.id); } } /** * 获取报表数据 * * @param {Object} ctx - egg全局context * @return {void} */ async getReport(ctx) { try { // console.log('in getReport'); const params = JSON.parse(ctx.request.body.params); // console.log(params); let rptTpl = await ctx.service.rptTpl.getTplById(params.rpt_tpl_id); if (!rptTpl || rptTpl.length !== 1) { throw '获取模板失败'; } rptTpl = JSON.parse(rptTpl[0].rpt_content); // console.log('get the template!'); // test const pageRst = await getAllPagesCommon(ctx, rptTpl, params, JV.PAGING_OPTION_NORMAL, JV.OUTPUT_TYPE_NORMAL); // console.log(pageRst); /* // -------------------------- const printCom = JpcEx.createNew(); const defProperties = await ctx.service.rptPreDefineCfg.getCfgById('Administrator'); // console.log(rptTpl); rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = pageSize; printCom.initialize(rptTpl); // console.log('initialize the template!'); const pageRst = printCom.outputAsPreviewPage(rptTpl, JSON.parse(defProperties[0].defined_content)); // console.log(pageRst); */ ctx.body = { data: pageRst }; // ctx.body = { data: { msg: 'test the network' } }; ctx.status = 201; } catch (ex) { this.setMessage(ex.toString(), this.messageType.ERROR); } } } return ReportController; }; async function getReportData(ctx, params, filters) { const rst = {}; const runnableRst = []; const runnableKey = []; // 这个配合runnableRst用,未来考虑并行查询优化 for (const filter of filters) { switch (filter) { case 'project' : runnableRst.push(ctx.service.project.getProjectById(params.project_id)); runnableKey.push('project'); break; case 'tender_info' : runnableRst.push(ctx.service.tenderInfo.getTenderInfo(params.tender_id)); runnableKey.push('tender_info'); break; case 'ledger' : runnableRst.push(ctx.service.ledger.getDataByTenderId(params.tender_id, 0)); runnableKey.push('ledger'); break; case 'stage_bills': runnableRst.push(ctx.service.stageBills.getLastestStageData(params.tender_id, params.stage_id)); runnableKey.push('stage_bills'); break; case 'stage_bills_final': runnableRst.push(ctx.service.stageBillsFinal.getFinalDataEx(params.tender_id, params.stage_order)); runnableKey.push('stage_bills_final'); break; case 'stage': runnableRst.push(ctx.service.stage.getStageById(params.stage_id)); runnableKey.push('stage'); break; case 'stage_pay': runnableRst.push(ctx.service.stagePay.getAuditorStageData(params.stage_id, params.stage_times, params.stage_order)); runnableKey.push('stage_pay'); break; default: break; } } const queryRst = await Promise.all(runnableRst); for (let idx = 0; idx < runnableKey.length; idx++) { rst[runnableKey[idx]] = queryRst[idx]; // console.log(runnableKey[idx]); // if (rst[runnableKey[idx]] instanceof Array) console.log('is Array') // else console.log('is not Array'); } return rst; } async function getAllPagesCommon(ctx, rptTpl, params, option, outputType) { // let rptTpl = null; const rptDataUtil = new rptDataExtractor(); rptDataUtil.initialize(rptTpl); // console.log(rptTpl); const filter = rptDataUtil.getDataRequestFilter(); // console.log(filter.tables); const rawDataObj = await getReportData(ctx, params, filter.tables); // console.log(rawDataObj); try { // console.log('before assemble'); const tplData = rptDataUtil.assembleData(rawDataObj); // console.log(tplData); const printCom = JpcEx.createNew(); if (params.pageSize) rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = params.pageSize; if (params.orientation && (params.orientation !== 'null')) rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] = params.orientation; let defProperties = await ctx.service.rptPreDefineCfg.getCfgById('Administrator'); // console.log('defProperties: '); // console.log(defProperties[0].defined_content); defProperties = JSON.parse(defProperties[0].defined_content); if (params.custCfg) { setupCustomizeCfg(params.custCfg, rptTpl, defProperties); } else { // setupCustomizeCfg(defProperties, rptTpl, defProperties); } const dftOption = params.option || JV.PAGING_OPTION_NORMAL; printCom.initialize(rptTpl); printCom.analyzeData(rptTpl, tplData, defProperties, dftOption, outputType); const maxPages = printCom.totalPages; let pageRst = null; if (maxPages > 0) { pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties, params.custCfg); } else { pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties); } if (pageRst) { // fsUtil.writeObjToFile(pageRst, 'D:/GitHome/temp/testBuiltPageResult.jsp'); } else { // } // console.log(pageRst); return pageRst; } catch (ex) { // console.log("报表数据异常: userId " + user_id + ", project id: " + prj_id); console.log(ex); } } function setupCustomizeCfg(customizeCfg, rptTpl, defProperties) { const tmpObj = {}; // 1. 字体 const newFonts = []; for (const font of defProperties.fonts) { const copyFont = {}; copyFont.ID = font.ID; for (const fontProp of JV.FONT_PROPS) { copyFont[fontProp] = font[fontProp]; } newFonts.push(copyFont); tmpObj[font.ID] = copyFont; } const private_setup_font = function(propStr, newFont) { if (tmpObj[propStr]) { tmpObj[propStr].Name = newFont.Name; tmpObj[propStr].FontHeight = String(newFont.FontHeight); tmpObj[propStr].FontBold = newFont.FontBold; tmpObj[propStr].FontItalic = newFont.FontItalic; tmpObj[propStr].FontUnderline = newFont.FontUnderline; } }; for (const custFont of customizeCfg.fonts) { switch (custFont.CfgDispName) { case '表标题': private_setup_font('ReportTitle_Main', custFont); break; case '列标题': private_setup_font('HeaderColumn', custFont); private_setup_font('FooterColumn', custFont); break; case '正文内容': private_setup_font('Content', custFont); break; case '合计': private_setup_font('GrandTotal', custFont); private_setup_font('SectionTotal', custFont); break; case '表眉/表脚': private_setup_font('Header', custFont); private_setup_font('Footer', custFont); break; default: break; } } // 1.1 窄体 if (tmpObj.Content_Narrow) { if (customizeCfg.isNarrow) { tmpObj.Content_Narrow.Name = 'Arial Narrow'; } else { if (tmpObj.Content) { tmpObj.Content_Narrow.Name = tmpObj.Content.Name; } else { tmpObj.Content_Narrow.Name = '宋体'; } } } defProperties.fonts = newFonts; // 2. 页边距 rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT] = customizeCfg.margins[JV.PROP_LEFT] / 10; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT] = customizeCfg.margins[JV.PROP_RIGHT] / 10; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_TOP] = customizeCfg.margins[JV.PROP_TOP] / 10; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM] = customizeCfg.margins[JV.PROP_BOTTOM] / 10; // 3. 边框竖线 if (!(customizeCfg.showVerticalLine)) { const private_copy_border = function(src) { const rst = {}; rst.Position = src.Position; rst.LineWeight = src.LineWeight; rst.DashStyle = src.DashStyle; rst.Color = src.Color; return rst; }; const newStyles = []; for (let i = 0; i < defProperties.styles.length; i++) { const style = defProperties.styles[i]; newStyles.push(style); if (style.ID === 'BORDER_ALL_AROUND') { const newStyle = {}; newStyle.ID = style.ID; newStyle.CfgDispName = style.CfgDispName; newStyle.border_style = []; for (const border of style.border_style) { const newBorder = private_copy_border(border); newStyle.border_style.push(newBorder); if (border.Position === 'Left' || border.Position === 'Right') { newBorder.LineWeight = 0; } } newStyles[newStyles.length - 1] = newStyle; } } defProperties.styles = newStyles; } // 4. 补0 const private_Setup_Format = function(tabFields) { if (tabFields) { for (const tabField of tabFields) { if (tabField[JV.PROP_FORMAT]) { tabField[JV.PROP_FORMAT] = tabField[JV.PROP_FORMAT].replace(new RegExp('#', 'gm'), '0'); } } } }; if (customizeCfg.fillZero) { if (rptTpl[JV.NODE_FLOW_INFO]) { if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_CONTENT]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_CONTENT][JV.PROP_FLOW_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_PAGE_SUM]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_PAGE_SUM][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_SEG_SUM]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_SEG_SUM][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP] && rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO][JV.NODE_DISCRETE_INFO]) { for (const discrete of rptTpl[JV.NODE_FLOW_INFO][JV.NODE_DISCRETE_INFO]) { private_Setup_Format(discrete[JV.PROP_DISCRETE_FIELDS]); } } if (rptTpl[JV.NODE_FLOW_INFO_EX]) { if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_CONTENT]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_CONTENT][JV.PROP_FLOW_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_PAGE_SUM]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_PAGE_SUM][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_SEG_SUM]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_SEG_SUM][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP] && rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES]) private_Setup_Format(rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_FLOW_GROUP][JV.PROP_GROUP_LINES][JV.PROP_SUM_FIELDS]); if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_DISCRETE_INFO]) { for (const discrete of rptTpl[JV.NODE_FLOW_INFO_EX][JV.NODE_DISCRETE_INFO]) { private_Setup_Format(discrete[JV.PROP_DISCRETE_FIELDS]); } } } } else if (rptTpl[JV.NODE_BILL_INFO]) { if (rptTpl[JV.NODE_BILL_INFO][JV.NODE_BILL_CONTENT]) private_Setup_Format(rptTpl[JV.NODE_BILL_INFO][JV.NODE_BILL_CONTENT][JV.PROP_BILL_FIELDS]); if (rptTpl[JV.NODE_BILL_INFO][JV.NODE_DISCRETE_INFO]) { for (const discrete of rptTpl[JV.NODE_BILL_INFO][JV.NODE_DISCRETE_INFO]) { private_Setup_Format(discrete[JV.PROP_DISCRETE_FIELDS]); } } } else if (rptTpl[JV.NODE_CROSS_INFO]) { if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_CONTENT]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_CONTENT][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL_SUM]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL_SUM][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW_EXT]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW_EXT][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW_SUM_EXT]) private_Setup_Format(rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW_SUM_EXT][JV.TAB_CROSS_FIELDS]); if (rptTpl[JV.NODE_CROSS_INFO][JV.NODE_DISCRETE_INFO]) { for (const discrete of rptTpl[JV.NODE_CROSS_INFO][JV.NODE_DISCRETE_INFO]) { private_Setup_Format(discrete[JV.PROP_DISCRETE_FIELDS]); } } } } }