| 
					
				 | 
			
			
				@@ -402,6 +402,7 @@ module.exports = app => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 throw '获取模板失败'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             rptTpl = JSON.parse(rptTpl[0].rpt_content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            rptTpl.id = params.rpt_tpl_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // console.log('get the template!'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const 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, params.rpt_tpl_id) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -894,20 +895,6 @@ module.exports = app => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 const data = JSON.parse(ctx.request.body.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 await this.ctx.service.rptCustomDefine.saveCustomSelect(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // const sid = data.gather_select ? -1 : data.stage_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // const filter = {tid: data.tender_id, sid: sid, rid: data.rpt_tpl_id}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // const count = await ctx.service.rptCustomDefine.count(filter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // const updateData = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // if (data.audit_select) updateData.audit_select = JSON.stringify(data.audit_select); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // if (data.gather_select) updateData.gather_select = JSON.stringify(data.gather_select); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // if (count > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //     await ctx.service.rptCustomDefine.update(updateData, filter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //     updateData.tid = data.tender_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //     updateData.sid = sid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //     updateData.rid = data.rpt_tpl_id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                //     await ctx.service.rptCustomDefine.db.insert(ctx.service.rptCustomDefine.tableName, updateData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                // } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 const result = await this._getReport(ctx, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ctx.body = { err: 0, msg: '', data: result }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } catch (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -919,328 +906,6 @@ module.exports = app => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return ReportController; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-async function checkStg(ctx, params) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (ctx.stage === null || ctx.stage === undefined || parseInt(ctx.stage.id) !== parseInt(params.stage_id)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        await ctx.service.stage.checkStage(params.stage_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ctx.stage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            params.stage_order = ctx.stage.curOrder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-async function 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 id = rptTpls[rtIdx].id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        rptTpls[rtIdx] = JSON.parse(rptTpls[rtIdx].rpt_content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        rptTpls[rtIdx].id = id; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    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(params, filterTables, memFieldKeys, customDefine, customSelect); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // const rawDataObj = await ctx.service.report.getReportData(params, filterTables, memFieldKeys, {}, {}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const rptPageRstArray = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 1. 这里只用一份数据,根据实际应用情况,先备份 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // const backupData = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // for (let filterIdx = 0; filterIdx < filterTables.length; filterIdx++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //     backupData[filterTables[filterIdx]] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //     Object.assign(backupData[filterTables[filterIdx]], rawDataObj[filterTables[filterIdx]]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 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(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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            printCom.analyzeData(ctx.helper, rptTpl, tplData, defProperties, dftOption, outputType, customSelect); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            rptPageRstArray.push(pageRst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 注意:这里需要把备份数据assign回去!!! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // if (tplIdx < rptTpls.length - 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //     for (let filterIdx = 0; filterIdx < filterTables.length; filterIdx++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //         backupData[filterTables[filterIdx]] = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //         Object.assign(rawDataObj[filterTables[filterIdx]], backupData[filterTables[filterIdx]]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            //     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        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 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-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 isFileExisted(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return new Promise(function(resolve, reject) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fs.access(file, err => { 
			 |