jpc_ex.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. let JV = require('./jpc_value_define');
  2. let JpcBand = require('./jpc_band');
  3. let JpcFlowTab = require('./jpc_flow_tab');
  4. let JpcBillTab = require('./jpc_bill_tab');
  5. let JpcCrossTab = require('./jpc_cross_tab');
  6. let JpcField = require('./jpc_field');
  7. let JpcParam = require('./jpc_param');
  8. let JpcFunc = require('./jpc_function');
  9. let JpcData = require('./jpc_data');
  10. let JpcCommonHelper = require('./helper/jpc_helper_common');
  11. let $JE = require('./jpc_rte'); //Important: for self-define function execution purpose
  12. let JpcExSrv = function(){};
  13. JpcExSrv.prototype.createNew = function(){
  14. function private_buildDftItems(rptTpl, dftCollection, propArray, nodeName) {
  15. let rst = {};
  16. if (dftCollection) {
  17. for (let i = 0; i < dftCollection.length; i++) {
  18. let item = {};
  19. for (let j = 0; j < propArray.length; j++) {
  20. item[propArray[j]] = dftCollection[i][propArray[j]];
  21. }
  22. rst[dftCollection[i][JV.PROP_ID]] = item;
  23. }
  24. if (rptTpl && rptTpl[nodeName] && rptTpl[nodeName].length > 0) {
  25. for (let i = 0; i < rptTpl[nodeName].length; i++) {
  26. let rptDftItem = rptTpl[nodeName][i];
  27. if (rst[rptDftItem[JV.PROP_ID]] === undefined) {
  28. let item = {};
  29. for (let j = 0; j < propArray.length; j++) {
  30. item[propArray[j]] = rptDftItem[propArray[j]];
  31. }
  32. rst[rptDftItem[JV.PROP_ID]] = item;
  33. }
  34. }
  35. }
  36. }
  37. return rst;
  38. }
  39. function private_buildDftControls(rptTpl, dftControlCollection) {
  40. return private_buildDftItems(rptTpl,dftControlCollection, JV.CONTROL_PROPS, JV.NODE_CONTROL_COLLECTION);
  41. }
  42. function private_buildDftFonts(rptTpl, dftFontCollection) {
  43. return private_buildDftItems(rptTpl,dftFontCollection, JV.FONT_PROPS, JV.NODE_FONT_COLLECTION);
  44. }
  45. function private_buildDftStyles(rptTpl, dftStyleCollection) {
  46. let rst = {};
  47. if (dftStyleCollection) {
  48. for (let i = 0; i < dftStyleCollection.length; i++) {
  49. let item = {};
  50. if (dftStyleCollection[i][JV.PROP_BORDER_STYLE] && dftStyleCollection[i][JV.PROP_BORDER_STYLE].length > 0) {
  51. for (let j = 0; j < dftStyleCollection[i][JV.PROP_BORDER_STYLE].length; j++) {
  52. let borderItem = {};
  53. for (let k = 0; k < JV.BORDER_STYLE_PROPS.length; k++) {
  54. borderItem[JV.BORDER_STYLE_PROPS[k]] = dftStyleCollection[i][JV.PROP_BORDER_STYLE][j][JV.BORDER_STYLE_PROPS[k]];
  55. }
  56. item[dftStyleCollection[i][JV.PROP_BORDER_STYLE][j][JV.PROP_POSITION]] = borderItem;
  57. }
  58. }
  59. rst[dftStyleCollection[i][JV.PROP_ID]] = item;
  60. }
  61. if (rptTpl && rptTpl[JV.NODE_STYLE_COLLECTION] && rptTpl[JV.NODE_STYLE_COLLECTION].length > 0) {
  62. for (let i = 0; i < rptTpl[JV.NODE_STYLE_COLLECTION].length; i++) {
  63. let rptDftItem = rptTpl[JV.NODE_STYLE_COLLECTION][i];
  64. if (rst[rptDftItem[JV.PROP_ID]] === undefined) {
  65. let item = {};
  66. for (let j = 0; j < rptDftItem[JV.PROP_BORDER_STYLE].length; j++) {
  67. let borderItem = {};
  68. for (let k = 0; k < JV.BORDER_STYLE_PROPS.length; k++) {
  69. borderItem[JV.BORDER_STYLE_PROPS[k]] = rptDftItem[JV.PROP_BORDER_STYLE][j][JV.BORDER_STYLE_PROPS[k]];
  70. }
  71. item[rptDftItem[JV.PROP_BORDER_STYLE][j][JV.PROP_POSITION]] = borderItem;
  72. }
  73. rst[rptDftItem[JV.PROP_ID]] = item;
  74. }
  75. }
  76. }
  77. }
  78. return rst;
  79. }
  80. let JpcResult = {};
  81. //JpcResult.report_title
  82. JpcResult.initialize = function(rptTpl) {
  83. let me = this;
  84. if (rptTpl[JV.NODE_FLOW_INFO]) {
  85. me.flowTab = JpcFlowTab.createNew();
  86. me.flowTab.initialize(false);
  87. me.isFollowMode = false;
  88. }
  89. if (rptTpl[JV.NODE_FLOW_INFO_EX]) {
  90. me.flowTabEx = JpcFlowTab.createNew();
  91. me.flowTabEx.initialize(true);
  92. if (rptTpl[JV.NODE_FLOW_INFO_EX][JV.PROP_FLOW_EX_DISPLAY_MODE] === JV.DISPLAY_MODE_FOLLOW) {
  93. me.isFollowMode = true;
  94. }
  95. }
  96. if (rptTpl[JV.NODE_BILL_INFO]) {
  97. me.billTab = JpcBillTab.createNew();
  98. me.billTab.initialize();
  99. }
  100. //let dt1 = new Date();
  101. if (rptTpl[JV.NODE_CROSS_INFO]) {
  102. me.crossTab = JpcCrossTab.createNew();
  103. me.crossTab.initialize();
  104. }
  105. me.totalPages = 0;
  106. me.exTotalPages = 0;
  107. me.runTimePageData = {};
  108. me.fields = JpcField.createNew(rptTpl);
  109. me.params = JpcParam.createNew(rptTpl);
  110. me.formulas = JpcFunc.createNew(rptTpl);
  111. };
  112. JpcResult.analyzeData = function(rptTpl, dataObj, defProperties, option) {
  113. let me = this, dftPagingOption = option||JV.PAGING_OPTION_NORMAL;
  114. //1. data object
  115. let dataHelper = JpcData.createNew();
  116. dataHelper.analyzeData(rptTpl, dataObj);
  117. //2. tab object
  118. //pre-condition: the data should be sorted in SQL/NoSQL level!
  119. //let dt1 = new Date();
  120. if (me.flowTab) {
  121. me.flowTab.sorting(rptTpl, dataObj, dataHelper.dataSeq.slice(0));
  122. if (me.flowTabEx) {
  123. me.flowTabEx.sorting(rptTpl, dataObj, dataHelper.exDataSeq.slice(0));
  124. }
  125. }
  126. if (me.billTab) {
  127. me.billTab.sorting(rptTpl, dataObj, dataHelper.dataSeq.slice(0));
  128. }
  129. if (me.crossTab) {
  130. me.crossTab.sorting(rptTpl, dataObj, dataHelper.dataSeq.slice(0));
  131. }
  132. //let dt2 = new Date();
  133. //alert(dt2 - dt1);
  134. //3. formulas
  135. me.executeFormulas(JV.RUN_TYPE_BEFORE_PAGING, rptTpl, dataObj, me);
  136. //4. paging
  137. me.paging(rptTpl, dataObj, defProperties, dftPagingOption);
  138. //alert('analyzeData was completed!');
  139. //for garbage collection:
  140. dataHelper = null;
  141. };
  142. JpcResult.paging = function(rptTpl, dataObj, defProperties, option) {
  143. let me = this, dftPagingOption = option||JV.PAGING_OPTION_NORMAL;
  144. if (me.flowTab) {
  145. if (me.isFollowMode) {
  146. me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, me.flowTabEx);
  147. } else {
  148. me.totalPages = me.flowTab.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null);
  149. if (me.flowTabEx) {
  150. me.exTotalPages = me.flowTabEx.preSetupPages(rptTpl, dataObj, defProperties, dftPagingOption, me, null);
  151. //console.log('ad-hoc flow pages: ' + me.exTotalPages);
  152. }
  153. me.totalPages += me.exTotalPages;
  154. }
  155. } else if (me.crossTab) {
  156. //me.totalPages = me.crossTab.preSetupPages(rptTpl, defProperties, dftPagingOption);
  157. me.totalPages = me.crossTab.preSetupPages(rptTpl, defProperties, JV.PAGING_OPTION_NORMAL); //infinity对交叉表来说无意义
  158. } else if (me.billTab) {
  159. me.totalPages = me.billTab.paging(rptTpl, dataObj);
  160. }
  161. };
  162. JpcResult.executeFormulas = function(runType, $CURRENT_TEMPLATE, $CURRENT_DATA, $CURRENT_RPT) {
  163. let me = this;
  164. for (let i = 0; i < me.formulas.length; i++) {
  165. if (me.formulas[i][JV.PROP_RUN_TYPE] === runType) {
  166. let expression = me.formulas[i][JV.PROP_EXPRESSION];
  167. if (expression) {
  168. let $ME = me.formulas[i];
  169. // console.log(expression);
  170. eval(expression);
  171. }
  172. }
  173. }
  174. };
  175. JpcResult.outputAsSimpleJSONPageArray = function(rptTpl, dataObj, startPage, endPage, defProperties) {
  176. let me = this, rst = {};
  177. if ((startPage > 0) && (startPage <= endPage) && (endPage <= me.totalPages)) {
  178. rst[JV.NODE_CONTROL_COLLECTION] = private_buildDftControls(rptTpl, (defProperties === null)?null:defProperties.ctrls);
  179. rst[JV.NODE_STYLE_COLLECTION] = private_buildDftStyles(rptTpl, (defProperties === null)?null:defProperties.styles);
  180. rst[JV.NODE_FONT_COLLECTION] = private_buildDftFonts(rptTpl, (defProperties === null)?null:defProperties.fonts);
  181. rst[JV.NODE_PAGE_INFO] = {};
  182. rst[JV.NODE_PAGE_INFO][JV.NODE_MAIN_INFO_RPT_NAME] = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MAIN_INFO_RPT_NAME];
  183. rst[JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE] = JpcCommonHelper.getPageSize(rptTpl);
  184. rst[JV.NODE_PAGE_INFO][JV.NODE_MARGINS] = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS];
  185. rst.items = [];
  186. let bands = JpcBand.createNew(rptTpl, defProperties);
  187. try {
  188. for (let page = startPage; page <= endPage; page++) {
  189. me.runTimePageData.currentPage = page;
  190. me.executeFormulas(JV.RUN_TYPE_BEFORE_OUTPUT, rptTpl, dataObj, me);
  191. rst.items.push(me.outputAsSimpleJSONPage(rptTpl, dataObj, bands, page, rst[JV.NODE_CONTROL_COLLECTION]));
  192. }
  193. if (bands[JV.BAND_PROP_MERGE_BAND]) {
  194. let mergedBand = {}, band = bands[JV.BAND_PROP_MERGE_BAND];
  195. mergedBand[JV.PROP_LEFT] = parseInt(band[JV.PROP_LEFT].toFixed(0));
  196. mergedBand[JV.PROP_RIGHT] = parseInt(band[JV.PROP_RIGHT].toFixed(0));
  197. mergedBand[JV.PROP_TOP] = parseInt(band[JV.PROP_TOP].toFixed(0));
  198. mergedBand[JV.PROP_BOTTOM] = parseInt(band[JV.PROP_BOTTOM].toFixed(0));
  199. mergedBand[JV.BAND_PROP_STYLE] = band[JV.BAND_PROP_STYLE];
  200. rst[JV.BAND_PROP_MERGE_BAND] = mergedBand;
  201. }
  202. } catch(exception) {
  203. console.log(exception);
  204. } finally {
  205. bands = null;
  206. }
  207. }
  208. return rst;
  209. };
  210. JpcResult.outputAsSimpleJSONPage = function(rptTpl, dataObj, bands, page, controls) {
  211. let me = this, rst = null;
  212. function getPageMergeBorder() {
  213. let rst = null;
  214. if (bands[JV.BAND_PROP_MERGE_BAND]) {
  215. let mergedBand = bands[JV.BAND_PROP_MERGE_BAND];
  216. rst = {};
  217. rst[JV.PROP_LEFT] = parseInt(mergedBand[JV.PROP_LEFT].toFixed(0));
  218. rst[JV.PROP_RIGHT] = parseInt(mergedBand[JV.PROP_RIGHT].toFixed(0));
  219. rst[JV.PROP_TOP] = parseInt(mergedBand[JV.PROP_TOP].toFixed(0));
  220. rst[JV.PROP_BOTTOM] = parseInt(mergedBand[JV.PROP_BOTTOM].toFixed(0));
  221. }
  222. return rst;
  223. }
  224. if (me.totalPages >= page) {
  225. rst = {};
  226. rst[JV.PROP_PAGE_SEQ] = page;
  227. //rst.cells = [];
  228. let adHocMergePos = null;
  229. if (me.flowTab) {
  230. if (me.totalPages - me.exTotalPages >= page) {
  231. if (me.flowTab.paging_option === JV.PAGING_OPTION_INFINITY) {
  232. adHocMergePos = {};
  233. }
  234. rst[JV.PROP_CELLS] = me.flowTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, adHocMergePos, me);
  235. if (adHocMergePos) {
  236. adHocMergePos[JV.NODE_PAGE_SIZE] = JpcCommonHelper.getPageSize(rptTpl);
  237. rst[JV.PAGE_SPECIAL_MERGE_POS] = adHocMergePos;
  238. }
  239. } else {
  240. if (!me.isFollowMode) {
  241. rst[JV.PROP_CELLS] = me.flowTabEx.outputAsSimpleJSONPage(rptTpl, dataObj, page - (me.totalPages - me.exTotalPages), bands, controls, adHocMergePos, me);
  242. }
  243. }
  244. } else if (me.crossTab) {
  245. rst[JV.PROP_CELLS] = me.crossTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
  246. } else if (me.billTab) {
  247. rst[JV.PROP_CELLS] = me.billTab.outputAsSimpleJSONPage(rptTpl, dataObj, page, bands, controls, me);
  248. }
  249. if (!(me.flowTab && me.flowTab.paging_option === JV.PAGING_OPTION_INFINITY)) {
  250. let pageMergeBorder = getPageMergeBorder();
  251. if (pageMergeBorder) {
  252. rst[JV.PROP_PAGE_MERGE_BORDER] = pageMergeBorder;
  253. }
  254. }
  255. }
  256. return rst;
  257. };
  258. //JpcEx.rte.currentRptObj = JpcResult;
  259. return JpcResult;
  260. };
  261. export default new JpcExSrv();