'use strict'; /** * Created by Tony on 2023/4/14. */ const BaseService = require('../base/base_service'); const JpcEx = require('../reports/rpt_component/jpc_ex'); const JV = require('../reports/rpt_component/jpc_value_define'); const rpt_xl_util = require('../reports/util/rpt_excel_util'); const rptDataExtractor = require('../reports/util/rpt_calculation_data_util'); const RPT_DEF_PROPERTIES = require('../const/report_defined_properties'); const needCustomTables = [ 'mem_custom_select', 'mem_gather_stage_bills', 'mem_gather_deal_bills', 'mem_gather_stage_pay', 'mem_gather_tender_info', 'mem_stage_sum_bills', 'mem_stage_sum_pay', 'mem_jh_gather_im_change', 'mem_jh_im_change', 'mem_jh_gather_stage_bills_compare', 'mem_material_sum_gl', ]; const sourceTypeConst = require('../const/source_type'); module.exports = app => { class JpcReport extends BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = ''; this.dataId = ''; } async getAllPagesCommon(ctx, rptTpl, params, option, outputType, baseDir, customSelect) { const rptDataUtil = new rptDataExtractor(); rptDataUtil.initialize(rptTpl); const filter = rptDataUtil.getDataRequestFilter(); const rawDataObj = await ctx.service.report.getReportData(rptTpl.source_type, params, filter.tables, filter.memFieldKeys, rptTpl[JV.NODE_CUSTOM_DEFINE], customSelect); // console.log(rawDataObj); try { 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; const defProperties = RPT_DEF_PROPERTIES; const tplData = rptDataUtil.assembleData(ctx, rawDataObj, baseDir, printCom, customSelect); 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(ctx.helper, rptTpl, tplData, defProperties, dftOption, outputType, customSelect, params.splitArchives); const maxPages = printCom.totalPages; let pageRst = null; if (maxPages > 0) { pageRst = printCom.outputAsSimpleJSONPageArray(ctx.helper, rptTpl, tplData, 1, maxPages, defProperties, params.custCfg, customSelect); } else { pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties); } pageRst.id = params.rpt_tpl_id; if (tplData.splitArcPages) { pageRst.splitArcPages = tplData.splitArcPages; pageRst.splitArcPagesInfo = tplData.splitArcPagesInfo; } return pageRst; } catch (ex) { console.log('报表数据异常, tender id: ' + params.tender_id); console.log(ex); } } async getMultiRptsCommon(ctx, params, outputType, baseDir) { for (let idx = 0; idx < params.rpt_ids.length; idx++) { params.rpt_ids[idx] = parseInt(params.rpt_ids[idx]); // 转换一下,以防万一 } const rptTpls = await ctx.service.rptTpl.getAllTplByIds(params.rpt_ids); rptTpls.sort(function(rpt1, rpt2) { return params.rpt_ids.indexOf(rpt1.id) - params.rpt_ids.indexOf(rpt2.id); }); for (let rtIdx = 0; rtIdx < rptTpls.length; rtIdx++) { const newRptTpl = JSON.parse(rptTpls[rtIdx].rpt_content); newRptTpl.id = rptTpls[rtIdx].id; newRptTpl.source_type = rptTpls[rtIdx].source_type || sourceTypeConst.defaultSourceType; rptTpls[rtIdx] = newRptTpl; } const rptDataUtil = new rptDataExtractor(); const filterTables = []; const memFieldKeys = {}; let customSelect = {}; let customDefine = {}; for (const rptTpl of rptTpls) { rptDataUtil.initialize(rptTpl); const filter = rptDataUtil.getDataRequestFilter(); // console.log(filter); for (const table of filter.tables) { if (filterTables.indexOf(table) < 0 && needCustomTables.indexOf(table) < 0) { filterTables.push(table); } // memFieldKeys[table] = []; } for (const tableKeyProp in filter.memFieldKeys) { if (needCustomTables.indexOf(tableKeyProp) >= 0) continue; if (!memFieldKeys.hasOwnProperty(tableKeyProp)) { memFieldKeys[tableKeyProp] = []; } for (const mfKey of filter.memFieldKeys[tableKeyProp]) { if (memFieldKeys[tableKeyProp].indexOf(mfKey) < 0) { memFieldKeys[tableKeyProp].push(mfKey); } } } // 输出报表的时候要把客户选择的数据的参数加进来 let finCustomSelect = {}; if (rptTpl[JV.NODE_CUSTOM_DEFINE]) { finCustomSelect = rptTpl[JV.NODE_CUSTOM_DEFINE] && rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_AUDIT_SELECT].enable ? await ctx.service.rptCustomDefine.getCustomDefine(params.tender_id, params.stage_id, rptTpl.id) : await ctx.service.rptCustomDefine.getCustomDefine(params.tender_id, -1, rptTpl.id); } if (finCustomSelect) { customDefine = rptTpl[JV.NODE_CUSTOM_DEFINE]; customSelect = finCustomSelect; } } const rawDataObj = await ctx.service.report.getReportData(rptTpls[0].source_type, params, filterTables, memFieldKeys, customDefine, customSelect); // const rawDataObj = await ctx.service.report.getReportData(rptTpls[0].source_type, params, filterTables, memFieldKeys, {}, {}); try { const rptPageRstArray = []; // 2. 一个一个模板创建数据 // let defProperties = await ctx.service.rptPreDefineCfg.getCfgById('Administrator'); // defProperties = JSON.parse(defProperties[0].defined_content); const defProperties = RPT_DEF_PROPERTIES; for (let tplIdx = 0; tplIdx < rptTpls.length; tplIdx++) { const rptTpl = (rptTpls[tplIdx]._doc) ? rptTpls[tplIdx]._doc : rptTpls[tplIdx]; rptDataUtil.initialize(rptTpl); let customSelect = rptTpl[JV.NODE_CUSTOM_DEFINE] && rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_AUDIT_SELECT].enable ? await ctx.service.rptCustomDefine.getCustomDefine(params.tender_id, params.stage_id, rptTpl.id) : await ctx.service.rptCustomDefine.getCustomDefine(params.tender_id, -1, rptTpl.id); if (rptTpl[JV.NODE_CUSTOM_DEFINE] && rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_CHANGE_SELECT] && rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_CHANGE_SELECT].enable) { customSelect = { tid: params.tender_id, rid: params.rpt_tpl_id, sid: -1, change_select: params.customSelect[tplIdx].change_select }; } // 从汇总的rawDataObj中拷贝所需数据表至curRawDataObj,以供后续使用 const curRawDataObj = {}; const filter = rptDataUtil.getDataRequestFilter(); for (const table of filter.tables) { curRawDataObj[table] = ctx.helper.clone(rawDataObj[table]); } // 如果是用户交互类型的表,则应该单独获取数据 if ((params.customSelect && params.customSelect[tplIdx]) || rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_OPTION]) { const cfTables = [], cmFieldKeys = []; const curFilter = rptDataUtil.getDataRequestFilter(); for (const table of curFilter.tables) { if (needCustomTables.indexOf(table) >= 0) { cfTables.push(table); } } for (const tableKeyProp in filter.memFieldKeys) { if (needCustomTables.indexOf(tableKeyProp) < 0) continue; if (!cmFieldKeys.hasOwnProperty(tableKeyProp)) { cmFieldKeys[tableKeyProp] = []; } for (const mfKey of filter.memFieldKeys[tableKeyProp]) { if (cmFieldKeys[tableKeyProp].indexOf(mfKey) < 0) { cmFieldKeys[tableKeyProp].push(mfKey); } } } const customRawDataObj = await ctx.service.report.getReportData(rptTpl.source_type, params, cfTables, cmFieldKeys, rptTpl[JV.NODE_CUSTOM_DEFINE], customSelect); for (const prop in customRawDataObj) { curRawDataObj[prop] = customRawDataObj[prop]; } } const tplData = rptDataUtil.assembleData(ctx, curRawDataObj, baseDir, null, customSelect); const printCom = JpcEx.createNew(); rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = params.pageSize; 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; if (params.custCfg) setupCustomizeCfg(params.custCfg, rptTpl, defProperties); const dftOption = params.option || JV.PAGING_OPTION_NORMAL; printCom.initialize(rptTpl); // console.log(rptTpl); const dftSplitArchives = []; if (params.splitArchives[tplIdx]) { dftSplitArchives.push(params.splitArchives[tplIdx]); } // printCom.analyzeData(ctx.helper, rptTpl, tplData, defProperties, dftOption, outputType, customSelect, params.splitArchives); printCom.analyzeData(ctx.helper, rptTpl, tplData, defProperties, dftOption, outputType, customSelect, dftSplitArchives); const maxPages = printCom.totalPages; let pageRst = null; // console.log(maxPages); if (maxPages > 0) { pageRst = printCom.outputAsSimpleJSONPageArray(ctx.helper, rptTpl, tplData, 1, maxPages, defProperties, params.custCfg, customSelect); } else { pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties); } pageRst.id = rptTpl.id; if (tplData.splitArcPages) { pageRst.splitArcPages = tplData.splitArcPages; pageRst.splitArcPagesInfo = tplData.splitArcPagesInfo; } rptPageRstArray.push(pageRst); } return rptPageRstArray; } catch (ex) { console.log(`'报表数据异常(getMultiRptsCommon): project_id ${params.project_id}, tender_id: ${params.tender_id}, stage_id: ${params.stage_id}`); console.log(ex); } finally { // } } async getPreviewPagesWithDiscreteDataCommon(ctx, rawRptTpl, pageSize, baseDir, customSelect) { // 此方法是要获取带离散数据的预览页面 const rptTpl = JSON.parse(rawRptTpl.rpt_content); let params = null; if (ctx.params) { params = {}; params.tender_id = ctx.params.id; params.detail_id = ctx.params.did; } const rptDataUtil = new rptDataExtractor(); rptDataUtil.initialize(rptTpl); const filter = rptDataUtil.getDataRequestFilter(); const source_type = rawRptTpl.source_type; const rawDataObj = await ctx.service.report.getReportData(source_type, params, filter.tables, filter.memFieldKeys, rptTpl[JV.NODE_CUSTOM_DEFINE], null); try { const printCom = JpcEx.createNew(); rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = pageSize; const defProperties = RPT_DEF_PROPERTIES; const tplData = rptDataUtil.assembleData(ctx, rawDataObj, baseDir, printCom, customSelect); setupSomeDftCustomizeCfg(rptTpl); printCom.initialize(rptTpl); printCom.analyzeData(ctx.helper, rptTpl, tplData, defProperties, JV.PAGING_OPTION_NORMAL, JV.OUTPUT_TYPE_NORMAL, customSelect, []); const maxPages = printCom.totalPages; let pageRst = null; // if (maxPages > 0) { pageRst = printCom.outputAsSimpleJSONPageArray(ctx.helper, rptTpl, tplData, 1, 1, defProperties, params.custCfg, customSelect); } else { pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties); } return pageRst; } catch (ex) { console.log('报表数据异常, tender id: ' + params.tender_id); console.log(ex); } } async getAllPreviewPagesCommon(rawRptTpl, pageSize) { const printCom = JpcEx.createNew(); const defProperties = RPT_DEF_PROPERTIES; const rptTpl = JSON.parse(rawRptTpl.rpt_content); rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE] = pageSize; setupSomeDftCustomizeCfg(rptTpl); printCom.initialize(rptTpl); const pageRst = printCom.outputAsPreviewPage(rptTpl, defProperties); return pageRst; } } return JpcReport; }; 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.hasOwnProperty('borderThick')) { for (let i = 0; i < defProperties.styles.length; i++) { const style = defProperties.styles[i]; if (style.ID === 'BORDER_ALL_AROUND') { for (const border of style.border_style) { border.LineWeight = customizeCfg.borderThick; } } } } // 4. 边框竖线 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; } // 5. 补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]); } } } } } function setupSomeDftCustomizeCfg(rptTpl) { rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT] = 1.5; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT] = 1.5; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_TOP] = 1.5; rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM] = 1.5; }