rpt_calculation_data_util.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. 'use strict';
  2. /**
  3. * Created by Tony on 2019/6/18.
  4. * 计量报表数据提取class,是协助报表模板里指标字段自主提取数据的工具类
  5. */
  6. const JV = require('../rpt_component/jpc_value_define');
  7. const $JE = require('../rpt_component/jpc_rte');
  8. const fs = require('fs');
  9. const fsUtil = require('../../public/js/fsUtil');
  10. const stringUtil = require('../../public/js/stringUtil');
  11. const scMathUtil = require('../../public/js/scMathUtil');
  12. const data_analyze_util = require('../../lib/rpt_data_analysis').analysisObj;
  13. const _ = require('lodash');
  14. const treeUtil = require('../public/treeUtil');
  15. const RELATION_TABLES_KEYS = {
  16. project: { main_key: 'id' },
  17. tender: { main_key: 'id', foreign_key: { project: 'project_id' } },
  18. tender_info: { main_key: 'id', foreign_key: { project: 'pid', tender: 'tid' } },
  19. ledger: { main_key: 'id', isTree: true, tree_pid: 'ledger_pid', tree_id: 'ledger_id', foreign_key: { tender: 'tender_id' } },
  20. };
  21. const change_CONST = require('../../const/change');
  22. const TRANSLATE_CONST = {
  23. '变更令常量': {
  24. '变更类型': { keys: [], values: [] },
  25. '变更类别': { keys: [], values: [] },
  26. '变更性质': { keys: [], values: [] },
  27. '费用承担方' : { keys: [], values: [] },
  28. },
  29. };
  30. function _iniConstProperties(constName, constDtlName, destConstProp) {
  31. for (const propKey in destConstProp) {
  32. // TRANSLATE_CONST[constName][constDtlName]['_' + destConstProp[propKey].value] = destConstProp[propKey].name;
  33. TRANSLATE_CONST[constName][constDtlName].keys.push(destConstProp[propKey].value);
  34. TRANSLATE_CONST[constName][constDtlName].values.push(destConstProp[propKey].name);
  35. }
  36. }
  37. _iniConstProperties('变更令常量', '变更类型', change_CONST.type);
  38. _iniConstProperties('变更令常量', '变更类别', change_CONST.class);
  39. _iniConstProperties('变更令常量', '变更性质', change_CONST.quality);
  40. _iniConstProperties('变更令常量', '费用承担方', change_CONST.charge);
  41. class Rpt_Common {
  42. initialize(rpt_tpl, currentDataObj) {
  43. this.template = rpt_tpl;
  44. this.currentDataObj = currentDataObj;
  45. }
  46. Multiply(val1, val2, fixFormat) {
  47. const rst = [];
  48. let maxLen = val1.length;
  49. let minLen = val2.length;
  50. if (minLen > maxLen) {
  51. maxLen = maxLen + minLen; minLen = maxLen - minLen; maxLen = maxLen - minLen;
  52. }
  53. for (let i = 0; i < maxLen; i++) {
  54. let value = ((i < val1.length) ? val1[i] : val1[minLen - 1]) * ((i < val2.length) ? val2[i] : val2[minLen - 1]);
  55. if (value === null || value === undefined) {
  56. value = '0';
  57. }
  58. if (fixFormat) value = value.toFixed(fixFormat);
  59. rst.push(value);
  60. }
  61. return rst;
  62. }
  63. Divide(val1, val2, fixFormat) {
  64. const rst = [];
  65. let maxLen = val1.length;
  66. let minLen = val2.length;
  67. if (minLen > maxLen) {
  68. maxLen = maxLen + minLen; minLen = maxLen - minLen; maxLen = maxLen - minLen;
  69. }
  70. for (let i = 0; i < maxLen; i++) {
  71. let value = ((i < val1.length) ? val1[i] : val1[minLen - 1]) / ((i < val2.length) ? val2[i] : val2[minLen - 1]);
  72. if (fixFormat) value = value.toFixed(fixFormat);
  73. rst.push(value);
  74. }
  75. return rst;
  76. }
  77. Plus(val1, val2, fixFormat) {
  78. const rst = [];
  79. let maxLen = val1.length;
  80. let minLen = val2.length;
  81. if (minLen > maxLen) {
  82. maxLen = maxLen + minLen; minLen = maxLen - minLen; maxLen = maxLen - minLen;
  83. }
  84. for (let i = 0; i < maxLen; i++) {
  85. let value = ((i < val1.length) ? val1[i] : val1[minLen - 1]) + ((i < val2.length) ? val2[i] : val2[minLen - 1]);
  86. if (fixFormat) value = value.toFixed(fixFormat);
  87. rst.push(value);
  88. }
  89. return rst;
  90. }
  91. MultiPlus(arrVal, fixFormat) {
  92. const rst = [];
  93. for (let i = 0; i < arrVal.length; i++) {
  94. const valItem = arrVal[i];
  95. if (i === 0) {
  96. for (const dtl of valItem) {
  97. let value = parseFloat(dtl);
  98. if (fixFormat) value = value.toFixed(fixFormat);
  99. rst.push(value);
  100. }
  101. } else {
  102. for (let j = 0; j < valItem.length; j++) {
  103. if (j < rst.length) {
  104. let value = rst[j] + valItem[j];
  105. if (fixFormat) value = value.toFixed(fixFormat);
  106. rst[j] = value;
  107. } else {
  108. let value = parseFloat(valItem[j]);
  109. if (fixFormat) value = value.toFixed(fixFormat);
  110. rst.push(value);
  111. }
  112. }
  113. }
  114. }
  115. return rst;
  116. }
  117. Minus(val1, val2, fixFormat) {
  118. const rst = [];
  119. let maxLen = val1.length;
  120. let minLen = val2.length;
  121. if (minLen > maxLen) {
  122. maxLen = maxLen + minLen; minLen = maxLen - minLen; maxLen = maxLen - minLen;
  123. }
  124. for (let i = 0; i < maxLen; i++) {
  125. let value = ((i < val1.length) ? val1[i] : val1[minLen - 1]) - ((i < val2.length) ? val2[i] : val2[minLen - 1]);
  126. if (fixFormat) value = value.toFixed(fixFormat);
  127. rst.push(value);
  128. }
  129. return rst;
  130. }
  131. FormatString(arrVal, formatStr) {
  132. const rst = [];
  133. for (const val of arrVal) {
  134. rst.push(stringUtil.replaceAll(formatStr, '%S', val));
  135. }
  136. return rst;
  137. }
  138. }
  139. class Rpt_Data_Extractor {
  140. constructor() {
  141. this.COMMON = new Rpt_Common();
  142. }
  143. initialize(tpl) {
  144. this.rptTpl = tpl;
  145. }
  146. // 因为计量是采用传统的关系数据库(MySQL), 有一些表关系是需要先约定(如上下级关系,外键关系等)
  147. // 根据报表模板映射指标(非离散指标)的定义,罗列出所有需要用到的data对象key,作为数据请求的过滤依据
  148. getDataRequestFilter() {
  149. const rst = {};
  150. const memFieldKeys = {}; // 内存表优化用,需要获得相关内存表的指标请求,因为有些额外指标需要花资源去获得
  151. const tables = []; // 记录需要查询哪些表
  152. // const filters = []; // 记录过滤条件(预处理中的过滤),目前先不处理
  153. const tpl = this.rptTpl;
  154. const pri_func_split_mem_fieldKey = function(field) {
  155. // 计量需要获取所有内存表指标的key,优化用
  156. if (memFieldKeys[field.TableName] === undefined) {
  157. memFieldKeys[field.TableName] = [];
  158. }
  159. const strs = field[JV.PROP_FIELD_EXP_MAP].split("', '");
  160. if (strs.length === 2) {
  161. const codeKey = strs[1].slice(0, strs[1].indexOf("'"));
  162. if (field.TableName.indexOf('mem_') === 0 && memFieldKeys[field.TableName].indexOf(codeKey) < 0) {
  163. memFieldKeys[field.TableName].push(codeKey);
  164. }
  165. }
  166. };
  167. const pri_func_chk_filter = function(field) {
  168. // 计量的机制有所不同,数据分开保存在不同的表里,
  169. if (field.TableName && tables.indexOf(field.TableName) < 0) {
  170. tables.push(field.TableName);
  171. }
  172. pri_func_split_mem_fieldKey(field);
  173. };
  174. const pri_setup_filter = function(FIELD_LIST_KEY) {
  175. // console.log(tpl[JV.NODE_FIELD_MAP][FIELD_LIST_KEY]);
  176. if (tpl[JV.NODE_FIELD_MAP][FIELD_LIST_KEY]) {
  177. for (const field of tpl[JV.NODE_FIELD_MAP][FIELD_LIST_KEY]) {
  178. pri_func_chk_filter(field);
  179. }
  180. }
  181. };
  182. pri_setup_filter(JV.NODE_DISCRETE_FIELDS);
  183. pri_setup_filter(JV.NODE_MASTER_FIELDS);
  184. pri_setup_filter(JV.NODE_DETAIL_FIELDS);
  185. pri_setup_filter(JV.NODE_MASTER_FIELDS_EX);
  186. pri_setup_filter(JV.NODE_DETAIL_FIELDS_EX);
  187. if (tpl[JV.NODE_MAP_DATA_HANDLE_INFO] && tpl[JV.NODE_MAP_DATA_HANDLE_INFO].length > 0) {
  188. // 计量的预处理会有所变化,没有那么多方式,这里只记录过滤
  189. for (const preHandle of tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
  190. if (preHandle[JV.PROP_HANDLE_TYPE] === JV.PROP_HANDLE_TYPE_FILTER) {
  191. if (tables.indexOf(preHandle[JV.PROP_DATA_KEY]) < 0) {
  192. tables.push(preHandle[JV.PROP_DATA_KEY]);
  193. }
  194. // 目前还没想好有哪些过滤,骑驴找马吧
  195. }
  196. }
  197. }
  198. rst.tables = tables;
  199. rst.memFieldKeys = memFieldKeys;
  200. return rst;
  201. }
  202. // 装配数据(把收集到的数据,依据报表模板的指示,预处理(如:排序、过滤、合计)及装配到相关指标)
  203. assembleData(ctx, rawDataObj, baseDir, $CURRENT_RPT, customSelect) {
  204. const $PROJECT = { REPORT: {} };
  205. const tpl = this.rptTpl;
  206. this.COMMON.initialize(tpl, rawDataObj);
  207. $PROJECT.COMMON = this.COMMON;
  208. // console.log(rawDataObj);
  209. setupFunc($PROJECT.REPORT, rawDataObj, baseDir);
  210. if (tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
  211. for (const preHandle of tpl[JV.NODE_MAP_DATA_HANDLE_INFO]) {
  212. const srcData = getModuleDataByKey(rawDataObj.prjData, preHandle[JV.PROP_DATA_KEY]);
  213. switch (preHandle[JV.PROP_HANDLE_TYPE]) {
  214. case JV.PROP_HANDLE_TYPE_SORT:
  215. // sortData(srcData, preHandle, rawDataObj.prjData);
  216. break;
  217. case JV.PROP_HANDLE_TYPE_FILTER:
  218. // filterData(srcData, preHandle, rawDataObj.prjData);
  219. break;
  220. case JV.PROP_HANDLE_TYPE_PRE_DEFINED:
  221. preDefineProcess(ctx, tpl, preHandle, rawDataObj, $CURRENT_RPT, customSelect);
  222. break;
  223. default:
  224. break;
  225. }
  226. }
  227. }
  228. const rptDataObj = {};
  229. rptDataObj[JV.DATA_DISCRETE_DATA] = [];
  230. rptDataObj[JV.DATA_MASTER_DATA] = [];
  231. rptDataObj[JV.DATA_DETAIL_DATA] = [];
  232. rptDataObj[JV.DATA_MASTER_DATA_EX] = [];
  233. rptDataObj[JV.DATA_DETAIL_DATA_EX] = [];
  234. assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS], rptDataObj[JV.DATA_DISCRETE_DATA], $PROJECT);
  235. // console.log(JV.DATA_DISCRETE_DATA);
  236. // console.log(rptDataObj[JV.DATA_DISCRETE_DATA]);
  237. assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS], rptDataObj[JV.DATA_MASTER_DATA], $PROJECT);
  238. // console.log(JV.DATA_MASTER_DATA);
  239. // console.log(rptDataObj[JV.DATA_MASTER_DATA]);
  240. assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS], rptDataObj[JV.DATA_DETAIL_DATA], $PROJECT);
  241. // console.log(JV.DATA_DETAIL_DATA);
  242. // console.log(rptDataObj[JV.DATA_DETAIL_DATA]);
  243. assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS_EX], rptDataObj[JV.DATA_MASTER_DATA_EX], $PROJECT);
  244. // console.log(JV.DATA_MASTER_DATA_EX);
  245. // console.log(rptDataObj[JV.DATA_MASTER_DATA_EX]);
  246. assembleFields(tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS_EX], rptDataObj[JV.DATA_DETAIL_DATA_EX], $PROJECT);
  247. // console.log(JV.DATA_DETAIL_DATA_EX);
  248. // console.log(rptDataObj[JV.DATA_DETAIL_DATA_EX]);
  249. // fsUtil.writeObjToFile(rptDataObj, 'D:/GitHome/temp/insertedOriginalData.jsp');
  250. // fsUtil.writeObjToFile(rawDataObj, 'D:/GitHome/temp/insertedRawDataData.jsp');
  251. // fsUtil.writeObjToFile($PROJECT, 'D:/GitHome/temp/$PROJECTData.jsp');
  252. // fsUtil.writeObjToFile(tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS], 'D:/GitHome/temp/masterFieldsAfterAssemble.jsp');
  253. // fsUtil.writeObjToFile(tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS], 'D:/GitHome/temp/detailFieldsAfterAssemble.jsp');
  254. // fsUtil.writeObjToFile(tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS], 'D:/GitHome/temp/discreteFieldsAfterAssemble.jsp');
  255. return rptDataObj;
  256. }
  257. }
  258. function getModuleDataByKey(prjData, key) {
  259. let rst = null;
  260. if (prjData) {
  261. for (const item of prjData) {
  262. if (item.moduleName === key) {
  263. rst = item;
  264. break;
  265. }
  266. }
  267. }
  268. return rst;
  269. }
  270. function filterData(sourceData, handleCfg, prjData) {
  271. let rstArr = [];
  272. const tempRstArr = [];
  273. for (const item of getActDataArr(sourceData)) {
  274. if (item._doc) {
  275. tempRstArr.push(item._doc);
  276. } else {
  277. tempRstArr.push(item);
  278. }
  279. }
  280. const private_chkVal = function(src, compVal, compStr) {
  281. let rst = true;
  282. switch (compStr) {
  283. case '==' :
  284. rst = (src == compVal);
  285. break;
  286. case '===' :
  287. rst = (src === compVal);
  288. break;
  289. case '>' :
  290. rst = (src > compVal);
  291. break;
  292. case '>=' :
  293. rst = (src >= compVal);
  294. break;
  295. case '<' :
  296. rst = (src < compVal);
  297. break;
  298. case '<=' :
  299. rst = (src <= compVal);
  300. break;
  301. case '!=' :
  302. rst = (src != compVal);
  303. break;
  304. case '!==' :
  305. rst = (src !== compVal);
  306. break;
  307. case 'in' :
  308. if (compVal instanceof Array) {
  309. rst = compVal.indexOf(src) >= 0;
  310. } else {
  311. // string,需要转类型
  312. const newInCv = JSON.parse(compVal);
  313. if (newInCv instanceof Array) {
  314. rst = newInCv.indexOf(src) >= 0;
  315. } else {
  316. rst = false;
  317. }
  318. }
  319. break;
  320. case 'not in':
  321. if (compVal instanceof Array) {
  322. rst = compVal.indexOf(src) < 0;
  323. } else {
  324. // string,需要转类型
  325. const newNotInCv = JSON.parse(compVal);
  326. if (newNotInCv instanceof Array) {
  327. rst = (newNotInCv.indexOf(src) < 0);
  328. } else {
  329. rst = true;
  330. }
  331. }
  332. break;
  333. default:
  334. rst = true;
  335. }
  336. return rst;
  337. };
  338. const private_chkArrVal = function(arr, key, compVal, compStr) {
  339. let rst = false;
  340. if (arr.length > 0) {
  341. for (const arrItem of arr) {
  342. if (arrItem[key] !== undefined) {
  343. // 可以为null值去判断
  344. rst = private_chkVal(arrItem[key], compVal, compStr);
  345. }
  346. if (rst) {
  347. break;
  348. }
  349. }
  350. } else {
  351. // 在某些判断条件下(含有'非'判断),如arr没有数组项,默认结果反而是true
  352. switch (compStr) {
  353. case '!=' :
  354. case '!==' :
  355. case 'not in':
  356. rst = true;
  357. break;
  358. default:
  359. break;
  360. }
  361. }
  362. return rst;
  363. };
  364. const private_filter_compare = function(item, filterCfg) {
  365. const compareObj = {};
  366. let compRst = true;
  367. let curComparePrjData = null;
  368. let startIdx = 0;
  369. const private_ref_join = function(refKey, targetDataKey, targetPropertyKey) {
  370. let rst = null;
  371. let objDataArr = null;
  372. curComparePrjData = getModuleDataByKey(prjData, targetDataKey);
  373. try {
  374. if (curComparePrjData !== null) {
  375. objDataArr = getActDataArr(curComparePrjData);
  376. for (const dtl of objDataArr) {
  377. if (item[refKey] === dtl[targetPropertyKey]) {
  378. rst = dtl;
  379. break;
  380. }
  381. }
  382. }
  383. } finally {
  384. curComparePrjData = null;
  385. }
  386. return rst;
  387. };
  388. for (const cfg of filterCfg[JV.PROP_FILTER_KEYS]) {
  389. if (cfg[JV.PROP_FILTER_COMPARE_VAL]) {
  390. // 比较key值
  391. const keys = cfg.key.split('.');
  392. if (keys.length > 1) {
  393. let lastObj = item;
  394. for (let i = 0; i < keys.length - 1; i++) {
  395. if (keys[i].indexOf('ref_join(') === 0) {
  396. const params = keys[i].slice(9, keys[i].length - 1).split(',');
  397. if (params.length === 3) {
  398. lastObj = private_ref_join(params[0], params[1], params[2]);
  399. }
  400. if (!(lastObj)) {
  401. compRst = false;
  402. break;
  403. }
  404. } else {
  405. lastObj = item[keys[i]];
  406. if (!(lastObj)) {
  407. compRst = false;
  408. break;
  409. }
  410. }
  411. }
  412. if (lastObj) {
  413. if (lastObj instanceof Array) {
  414. compRst = private_chkArrVal(lastObj, keys[keys.length - 1], cfg[JV.PROP_FILTER_COMPARE_VAL], cfg[JV.PROP_FILTER_CONDITION]);
  415. } else {
  416. compRst = private_chkVal(lastObj[keys[keys.length - 1]], cfg[JV.PROP_FILTER_COMPARE_VAL], cfg[JV.PROP_FILTER_CONDITION]);
  417. }
  418. }
  419. } else {
  420. compRst = private_chkVal(item[cfg.key], cfg[JV.PROP_FILTER_COMPARE_VAL], cfg[JV.PROP_FILTER_CONDITION]);
  421. }
  422. } else if (cfg[JV.PROP_FILTER_COMPARE_OBJ] && cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY]) {
  423. // 通过其他对象来过滤
  424. if (!curComparePrjData) {
  425. curComparePrjData = getModuleDataByKey(prjData, cfg[JV.PROP_FILTER_COMPARE_OBJ]);
  426. }
  427. if (cfg[JV.PROP_FILTER_CONDITION] === 'in' || cfg[JV.PROP_FILTER_CONDITION] === 'not in') {
  428. let compareArr = null;
  429. if (!compareObj.hasOwnProperty(cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY] + startIdx.toString())) {
  430. compareObj[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY] + startIdx.toString()] = [];
  431. compareArr = compareObj[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY] + startIdx.toString()];
  432. for (const data of getActDataArr(curComparePrjData)) {
  433. if (compareArr.indexOf(data[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY]]) < 0) {
  434. compareArr.push(data[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY]]);
  435. }
  436. }
  437. } else {
  438. compareArr = compareObj[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY] + startIdx.toString()];
  439. }
  440. compRst = private_chkVal(item[cfg.key], compareArr, cfg[JV.PROP_FILTER_CONDITION]);
  441. } else {
  442. for (const data of getActDataArr(curComparePrjData)) {
  443. compRst = private_chkVal(item[cfg.key], data[cfg[JV.PROP_FILTER_COMPARE_OBJ_KEY]], cfg[JV.PROP_FILTER_CONDITION]);
  444. if (compRst) break;
  445. }
  446. }
  447. }
  448. startIdx++;
  449. if (!compRst) {
  450. break; // 有不符合条件的数据则退出(这里的判断条件是and关系)
  451. }
  452. }
  453. return compRst;
  454. };
  455. const private_sub_filter_compare = function(dtlItem, subFilters) {
  456. let cmpRst = false;
  457. for (const dtlCfg of subFilters) {
  458. cmpRst = private_filter_compare(dtlItem, dtlCfg);
  459. if (cmpRst) {
  460. if (dtlCfg[JV.PROP_OTHER_SUB_FILTER] && dtlCfg[JV.PROP_OTHER_SUB_FILTER].length > 0) {
  461. cmpRst = private_sub_filter_compare(dtlItem, dtlCfg[JV.PROP_OTHER_SUB_FILTER]);
  462. if (cmpRst) break;
  463. } else {
  464. break;
  465. }
  466. }
  467. }
  468. return cmpRst;
  469. };
  470. for (const item of tempRstArr) {
  471. if (private_filter_compare(item, handleCfg)) {
  472. rstArr.push(item);
  473. }
  474. }
  475. if (handleCfg[JV.PROP_OTHER_SUB_FILTER] && handleCfg[JV.PROP_OTHER_SUB_FILTER].length > 0) {
  476. const newRstArr = [];
  477. for (const dtlItem of rstArr) {
  478. const cmpRst = private_sub_filter_compare(dtlItem, handleCfg[JV.PROP_OTHER_SUB_FILTER]);
  479. if (cmpRst) {
  480. newRstArr.push(dtlItem);
  481. }
  482. }
  483. rstArr = newRstArr;
  484. }
  485. replaceActDataArr(sourceData, rstArr);
  486. // fsUtil.writeObjToFile(sourceData.data, 'D:/GitHome/ConstructionCost/tmp/filteredRst.jsp');
  487. }
  488. function getOrgFieldDefine(fieldId, tpl) {
  489. let rst = null;
  490. if (tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS]) {
  491. for (const field of tpl[JV.NODE_FIELD_MAP][JV.NODE_DISCRETE_FIELDS]) {
  492. if (field[JV.PROP_ID] === fieldId) {
  493. rst = field;
  494. break;
  495. }
  496. }
  497. }
  498. if (rst === null && tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS]) {
  499. for (const field of tpl[JV.NODE_FIELD_MAP][JV.NODE_MASTER_FIELDS]) {
  500. if (field[JV.PROP_ID] === fieldId) {
  501. rst = field;
  502. break;
  503. }
  504. }
  505. }
  506. if (rst === null && tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
  507. for (const field of tpl[JV.NODE_FIELD_MAP][JV.NODE_DETAIL_FIELDS]) {
  508. if (field[JV.PROP_ID] === fieldId) {
  509. rst = field;
  510. break;
  511. }
  512. }
  513. }
  514. // 不会让用户选择独立离散指标的
  515. return rst;
  516. }
  517. function preDefineProcess(ctx, tpl, preDefineCfg, rawDataObj, $CURRENT_RPT, customSelect) {
  518. // 依据约定,需要提供如右所示格式的数据:[{field: 'b_code', table: 'mem_stage_bills'}, {field: 'id', table: 'mem_stage_bills'}]
  519. // 指标对象的mapExpression 格式类似于: "$PROJECT.REPORT.getProperty('mem_stage_im_zl', 'calc_memo')"
  520. const fields = [];
  521. // console.log($CURRENT_RPT);
  522. if (preDefineCfg.fields) {
  523. for (const field of preDefineCfg.fields) {
  524. const tplF = getOrgFieldDefine(field[JV.PROP_FIELD_ID], tpl);
  525. const mapStr = tplF[JV.PROP_FIELD_EXP_MAP].split(','); // 如上,用逗号分割
  526. let start = 0;
  527. let end = 0;
  528. let cnt = 0;
  529. for (let idx = 0; idx < mapStr[1].length; idx++) {
  530. if (mapStr[1][idx] === '\'') {
  531. cnt++;
  532. if (cnt === 1) {
  533. start = idx;
  534. } else {
  535. end = idx;
  536. break;
  537. }
  538. }
  539. }
  540. const codeKey = mapStr[1].slice(start + 1, end);
  541. // console.log('field codeKey: ' + codeKey);
  542. const rstF = { field: codeKey, table: tplF.TableName };
  543. fields.push(rstF);
  544. }
  545. }
  546. const analysisKey = preDefineCfg[JV.PROP_HANDLE_TYPE_PRE_DEFINED_KEY];
  547. if (analysisKey && analysisKey !== '') {
  548. if (data_analyze_util[analysisKey]) {
  549. try {
  550. // 在预定义方式中,小麦处理原始数据,不需要
  551. let preSetup = preDefineCfg[JV.PROP_HANDLE_SELF_SETUP];
  552. try {
  553. if (preSetup) {
  554. preSetup = JSON.parse(preSetup);
  555. }
  556. } catch (ex) {
  557. ctx.helper.log(ex);
  558. }
  559. data_analyze_util[analysisKey].fun(ctx, rawDataObj, fields, preSetup, {
  560. tplDefine: tpl[JV.NODE_CUSTOM_DEFINE],
  561. cDefine: customSelect
  562. });
  563. } catch (err) {
  564. ctx.helper.log(err);
  565. throw '报表预处理数据出错';
  566. }
  567. } else {
  568. throw '报表预处理方法不存在';
  569. }
  570. }
  571. }
  572. function adjustData(sourceData, adjustCfg) {
  573. const rstArr = [];
  574. for (const item of getActDataArr(sourceData)) {
  575. if (item._doc) {
  576. rstArr.push(item._doc);
  577. } else {
  578. rstArr.push(item);
  579. }
  580. }
  581. for (const item of adjustCfg[JV.PROP_ADJUST_COLLECTION]) {
  582. for (const rec of rstArr) {
  583. if (item[JV.PROP_ADJUST_ACTION] === 'prefix') {
  584. rec[item.key] = item[JV.PROP_ADJUST_ACTION_VAL] + rec[item.key];
  585. } else if (item[JV.PROP_ADJUST_ACTION] === 'suffix') {
  586. rec[item.key] = rec[item.key] + item[JV.PROP_ADJUST_ACTION_VAL];
  587. }
  588. }
  589. }
  590. replaceActDataArr(sourceData, rstArr);
  591. }
  592. function sortData(sourceData, sortCfg, prjData) {
  593. let rst = getActDataArr(sourceData);
  594. const tempRstArr = [];
  595. const sortType = sortCfg[JV.PROP_SORT_TYPE];
  596. const srcData = getActDataArr(sourceData);
  597. for (const item of srcData) {
  598. if (item._doc) {
  599. tempRstArr.push(item._doc);
  600. } else {
  601. tempRstArr.push(item);
  602. }
  603. }
  604. function private_normal_sort(destArr, sortKeys) {
  605. destArr.sort(function(a, b) {
  606. let compRst = 0;
  607. for (const comp of sortKeys) {
  608. const reverse = (comp.order === 'ascend') ? 1 : (-1);
  609. //
  610. if (a[comp.key] > b[comp.key]) {
  611. compRst = reverse;
  612. break;
  613. } else if (a[comp.key] < b[comp.key]) {
  614. compRst = -reverse;
  615. break;
  616. }
  617. }
  618. return compRst;
  619. });
  620. }
  621. function private_parent_sort(parentArr, parentKeys, childArr, childKeys) {
  622. const tmpRst = {};
  623. const rst = [];
  624. for (const pItem of parentArr) {
  625. let pKey = 'key';
  626. for (const key of parentKeys) {
  627. pKey += '_' + pItem[key];
  628. }
  629. tmpRst[pKey] = [];
  630. }
  631. for (const cItem of childArr) {
  632. let cKey = 'key';
  633. for (const key of childKeys) {
  634. cKey += '_' + cItem[key];
  635. }
  636. if (tmpRst[cKey]) {
  637. tmpRst[cKey].push(cItem);
  638. } else {
  639. // unknown child value! should be filtered!
  640. }
  641. }
  642. // childArr.splice(0);
  643. for (const pItem of parentArr) {
  644. let pKey = 'key';
  645. for (const key of parentKeys) {
  646. pKey += '_' + pItem[key];
  647. }
  648. rst.push(tmpRst[pKey]);
  649. // for (let rItem of tmpRst[pKey]) {
  650. // childArr.push(rItem);
  651. // }
  652. }
  653. return rst;
  654. }
  655. switch (sortType) {
  656. case 'tree':
  657. const addLevel = true;
  658. rst = treeUtil.buildTreeNodeDirectly(tempRstArr, addLevel);
  659. let newTopArr = [];
  660. if ((sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES] && sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES].length > 0) ||
  661. (sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES] && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].length > 0)) {
  662. const local_check_bills = function(tItem) {
  663. let chkDtl = false;
  664. if (tItem.flags && tItem.flags.length > 0) {
  665. for (const flagItem of tItem.flags) {
  666. if (sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].indexOf(flagItem.flag) >= 0) {
  667. newTopArr.push(tItem);
  668. chkDtl = true;
  669. break;
  670. }
  671. }
  672. }
  673. if (!chkDtl && tItem.items && tItem.items.length > 0) {
  674. for (const dtlItem of tItem.items) {
  675. local_check_bills(dtlItem);
  676. }
  677. }
  678. };
  679. for (const topItem of rst) {
  680. let chkTop = false;
  681. if (topItem.flags && topItem.flags.length > 0) {
  682. for (const flagItem of topItem.flags) {
  683. if (sortCfg[JV.PROP_FILTER_TOP_BILLS_NODES].indexOf(flagItem.flag) >= 0) {
  684. newTopArr.push(topItem);
  685. chkTop = true;
  686. break;
  687. }
  688. }
  689. }
  690. if (!chkTop && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES] && sortCfg[JV.PROP_FILTER_OTHER_BILLS_NODES].length > 0) {
  691. local_check_bills(topItem);
  692. }
  693. }
  694. } else {
  695. newTopArr = rst;
  696. }
  697. const destArr = [];
  698. // fsUtil.writeObjToFile(newTopArr, 'D:/GitHome/ConstructionCost/tmp/sortedAndFlattedRstBefore.jsp');
  699. treeUtil.getFlatArray(newTopArr, destArr, true);
  700. // console.log(destArr);
  701. replaceActDataArr(sourceData, destArr);
  702. // fsUtil.writeObjToFile(sourceData.data, 'D:/GitHome/ConstructionCost/tmp/sortedAndFlattedRst.jsp');
  703. break;
  704. case 'normal':
  705. private_normal_sort(tempRstArr, sortCfg[JV.PROP_SORT_KEYS]);
  706. replaceActDataArr(sourceData, tempRstArr);
  707. // fsUtil.writeObjToFile(sourceData.data, 'D:/GitHome/ConstructionCost/tmp/normalSortedRst.jsp');
  708. break;
  709. case 'accord_to_parent':
  710. const pcKey = sortCfg[JV.PROP_PARENT_CHILD_SORT_KEY];
  711. const parentSrcData = getModuleDataByKey(prjData, pcKey[JV.PROP_PARENT_DATA_KEY]);
  712. if (parentSrcData) {
  713. const tempParentArr = [];
  714. for (const item of getActDataArr(parentSrcData)) {
  715. if (item._doc) {
  716. tempParentArr.push(item._doc);
  717. } else {
  718. tempParentArr.push(item);
  719. }
  720. }
  721. const sortedRstArr = private_parent_sort(tempParentArr, pcKey[JV.PROP_PARENT_SORT_KEYS], tempRstArr, pcKey[JV.PROP_CHILD_SORT_KEYS]);
  722. if (sortCfg[JV.PROP_OTHER_SUB_SORT] && sortCfg[JV.PROP_OTHER_SUB_SORT].length > 0) {
  723. for (const sort of sortCfg[JV.PROP_OTHER_SUB_SORT]) {
  724. if (sort[JV.PROP_SORT_TYPE] === 'normal') {
  725. for (const subArr of sortedRstArr) {
  726. private_normal_sort(subArr, sort[JV.PROP_SORT_KEYS]);
  727. }
  728. } else if (sort[JV.PROP_SORT_TYPE] === 'self_define') {
  729. for (const subArr of sortedRstArr) {
  730. // console.log(subArr);
  731. const selfDefFunc = null;
  732. eval('selfDefFunc = ' + sort[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]);
  733. subArr.sort(selfDefFunc);
  734. // console.log(subArr);
  735. }
  736. }
  737. }
  738. }
  739. tempRstArr.splice(0);
  740. for (const item of sortedRstArr) {
  741. for (const subItem of item) {
  742. tempRstArr.push(subItem);
  743. }
  744. }
  745. }
  746. replaceActDataArr(sourceData, tempRstArr);
  747. break;
  748. case 'self_define':
  749. if (sortCfg[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]) {
  750. let selfDefFuncA = null;
  751. eval('selfDefFuncA = ' + sortCfg[JV.PROP_SORT_TYPE_SELF_DEFINE_LOGIC]);
  752. if (selfDefFuncA !== null) {
  753. tempRstArr.sort(selfDefFuncA);
  754. } else {
  755. console.log('sorting function is null!!!');
  756. }
  757. }
  758. replaceActDataArr(sourceData, tempRstArr);
  759. break;
  760. default:
  761. //
  762. }
  763. return rst;
  764. }
  765. function setupFunc(obj, ownRawObj, baseDir) {
  766. obj.myOwnRawDataObj = ownRawObj;
  767. obj.baseDir = baseDir;
  768. obj.getProperty = ext_getProperty;
  769. obj.getSplitProperty = ext_getSplitProperty;
  770. obj.getPicProperty = ext_getPicProperty;
  771. // obj.getPropertyByForeignId = ext_getPropertyByForeignId;
  772. obj.getPreferPrecisionProperty = ext_getPreferPrecisionProperty;
  773. obj.getArrayProperty = ext_getArrayValues;
  774. obj.getBlank = ext_getBlank;
  775. obj.translateConst = ext_translateConst; // 计量有些指标需要这样子来转换类型名称(即通过id得到名字)
  776. }
  777. function assembleFields(fieldList, rstDataArr, $PROJECT) {
  778. if (fieldList) {
  779. for (const field of fieldList) {
  780. shielded_exec_env($PROJECT, field, rstDataArr);
  781. if ('Precision' in field) {
  782. if (field.Precision.type === 'fixed') {
  783. // console.log('field.Precision.fixedMapExpression: ' + field.Precision.fixedMapExpression);
  784. const vrst = eval(field.Precision.fixedMapExpression);
  785. // console.log(vrst);
  786. if (vrst && vrst.length === 1) {
  787. field.fixedPrecisionNum = vrst[0];
  788. vrst.splice(0,1);
  789. }
  790. // console.log(field);
  791. } else if (field.Precision.type === 'flexible') {
  792. // console.log('field.Precision.flexibleMapExpression: ' + field.Precision.flexibleMapExpression);
  793. const vrst = eval(field.Precision.flexibleMapExpression);
  794. if (vrst && vrst.length === 1) {
  795. const tmpFlexObj = []; // 计量的动态精度对象与建筑/养护有所不同,需要重新生成
  796. for (const uKey in vrst[0]) {
  797. const tmpFObj = { unit: vrst[0][uKey].unit, decimal: vrst[0][uKey].value };
  798. if (uKey === 'other') {
  799. tmpFObj.unit = '其他未列单位';
  800. }
  801. tmpFlexObj.push(tmpFObj);
  802. }
  803. field.flexiblePrecisionRefObj = tmpFlexObj;
  804. vrst.splice(0, 1);
  805. }
  806. }
  807. }
  808. }
  809. }
  810. }
  811. function shielded_exec_env($PROJECT, $ME, rptDataItemObj) {
  812. if ($ME[JV.PROP_FIELD_EXP_MAP]) {
  813. rptDataItemObj.push(eval($ME[JV.PROP_FIELD_EXP_MAP]));
  814. }
  815. }
  816. function getActPropertyVal(firstPropKey, secPropKey, orgObj) {
  817. let rst = null;
  818. if (orgObj[firstPropKey]) {
  819. rst = orgObj[firstPropKey];
  820. } else if (orgObj[secPropKey]) {
  821. rst = orgObj[secPropKey];
  822. }
  823. return rst;
  824. }
  825. function getDeepProperty(propKey, orgObj, destArr) {
  826. const keys = propKey.split('.');
  827. const dftPropKey = 'key';
  828. const dftPropVal = 'value';
  829. const secDftPropVal = 'items';
  830. let parent = orgObj;
  831. let lastVal = null;
  832. for (const key of keys) {
  833. if (parent instanceof Array) {
  834. for (const item of parent) {
  835. if (item[dftPropKey] === key) {
  836. lastVal = getActPropertyVal(dftPropVal, secDftPropVal, item);
  837. break;
  838. }
  839. }
  840. } else {
  841. lastVal = null;
  842. if (parent[key] !== undefined) {
  843. lastVal = parent[key];
  844. } else if (parent[secDftPropVal]) {
  845. for (const item of parent[secDftPropVal]) {
  846. if (item[dftPropKey] === key) {
  847. // lastVal = item[dftPropVal];
  848. lastVal = getActPropertyVal(dftPropVal, secDftPropVal, item);
  849. break;
  850. }
  851. }
  852. }
  853. }
  854. parent = lastVal;
  855. if (parent === null) break;
  856. }
  857. if (destArr && destArr instanceof Array) {
  858. destArr.push(lastVal);
  859. }
  860. }
  861. function ext_getPreferPrecisionProperty(dataKey, preferKey, preferPropKey, dftPropKey) {
  862. // 通过一个开关(preferKey)来控制精度,如为true,则选择preferPropKey,否则选择dftPropKey
  863. const rst = [];
  864. const parentObj = this;
  865. const dtObj = parentObj.myOwnRawDataObj[dataKey];
  866. if (preferKey && preferPropKey && dftPropKey && dtObj) {
  867. const da = getActDataArr(dtObj);
  868. if (da.length === 1) {
  869. const pKey = [];
  870. pri_push_property(preferKey, da[0], pKey);
  871. if (pKey.length > 0 && pKey[0]) {
  872. pri_push_property(preferPropKey, da[0], rst);
  873. } else {
  874. pri_push_property(dftPropKey, da[0], rst);
  875. }
  876. }
  877. }
  878. return rst;
  879. }
  880. function ext_getProperty(dataKey, propKey) {
  881. const rst = [];
  882. const parentObj = this;
  883. const dtObj = parentObj.myOwnRawDataObj[dataKey];
  884. // console.log('dataKey: ' + dataKey);
  885. // console.log(dtObj);
  886. if (propKey && dtObj) {
  887. // console.log('---- dtObj[' + dataKey + '] ----');
  888. // console.log(dtObj[dataKey]);
  889. const da = getActDataArr(dtObj);
  890. // console.log(da);
  891. for (const dItem of da) {
  892. // const doc = (dItem._doc === null || dItem._doc === undefined) ? dItem : dItem._doc;
  893. pri_push_property(propKey, dItem, rst);
  894. }
  895. }
  896. // console.log('---- result ----');
  897. // console.log(rst);
  898. return rst;
  899. }
  900. function ext_getSplitProperty(dataKey, propKey, splitChar, index, dftValue) {
  901. const rst = [];
  902. const parentObj = this;
  903. const dtObj = parentObj.myOwnRawDataObj[dataKey];
  904. if (propKey && dtObj) {
  905. const da = getActDataArr(dtObj);
  906. for (const dItem of da) {
  907. pri_push_property(propKey, dItem, rst);
  908. }
  909. }
  910. // const rst = ext_getProperty(dataKey, propKey);
  911. for (let idx = 0; idx < rst.length; idx++) {
  912. if (typeof rst[idx] === 'string') {
  913. const splitArr = rst[idx].split(splitChar);
  914. if (splitArr.length > index) {
  915. rst[idx] = splitArr[index];
  916. } else {
  917. rst[idx] = dftValue;
  918. }
  919. }
  920. }
  921. return rst;
  922. }
  923. async function ext_getPicProperty(dataKey, propKey, isPath) {
  924. const rst = [];
  925. const parentObj = this;
  926. const dtObj = parentObj.myOwnRawDataObj[dataKey];
  927. if (propKey && dtObj) {
  928. const da = getActDataArr(dtObj);
  929. for (const dItem of da) {
  930. pri_push_property(propKey, dItem, rst);
  931. }
  932. if (isPath) {
  933. for (let picIdx = 0; picIdx < rst.length; picIdx++) {
  934. if (rst[picIdx] !== undefined && rst[picIdx] !== null && rst[picIdx] !== '') {
  935. const filePath = parentObj.baseDir + '/app/' + rst[picIdx];
  936. try {
  937. fs.accessSync(filePath, fs.constants.R_OK);
  938. const bData = fs.readFileSync(filePath);
  939. const base64Str = bData.toString('base64');
  940. const datauri = 'data:image/png;base64,' + base64Str;
  941. rst[picIdx] = datauri;
  942. // const res = await isFileExisted(filePath);
  943. // if (res) {
  944. // const bData = fs.readFileSync(filePath);
  945. // const base64Str = bData.toString('base64');
  946. // const datauri = 'data:image/png;base64,' + base64Str;
  947. // rst[picIdx] = datauri;
  948. // } else {
  949. // rst[picIdx] = ''; // 不存在图片,则设置为空,后续的方法就不会当作图片来处理了
  950. // }
  951. } catch (err) {
  952. rst[picIdx] = ''; // 不存在图片,则设置为空,后续的方法就不会当作图片来处理了
  953. console.error(err);
  954. }
  955. }
  956. }
  957. } else {
  958. // 不是路径,那么必须是image data,不用处理,正常走即可
  959. }
  960. }
  961. return rst;
  962. }
  963. function ext_getArrayValues(dataKey, itemKey) {
  964. const rst = [];
  965. const parentObj = this;
  966. const dtObj = parentObj.myOwnRawDataObj[dataKey];
  967. // 计量需要重写
  968. const keysArr = itemKey.split('.');
  969. const da = getActDataArr(dtObj);
  970. // console.log(keysArr);
  971. for (const dataItem of da) {
  972. let itemArr = [];
  973. if (keysArr.length <= 2) {
  974. if (dataItem[keysArr[0]] instanceof Array) {
  975. if (keysArr.length === 2) {
  976. for (const item of dataItem[keysArr[0]]) {
  977. itemArr.push(item[keysArr[1]]);
  978. }
  979. } else {
  980. itemArr = itemArr.concat(dataItem[keysArr[0]]);
  981. }
  982. } else {
  983. if (keysArr.length === 2) {
  984. const subProperty = dataItem[keysArr[0]][keysArr[1]];
  985. if (subProperty instanceof Array) {
  986. itemArr = itemArr.concat(subProperty);
  987. } else {
  988. itemArr.push(subProperty);
  989. }
  990. } else {
  991. itemArr.push(dataItem[keysArr[0]]);
  992. }
  993. }
  994. }
  995. rst.push(itemArr);
  996. // console.log(itemArr);
  997. }
  998. return rst;
  999. }
  1000. function ext_getBlank(dataKey, dftVal) {
  1001. const rst = [];
  1002. const parentObj = this;
  1003. const dtObj = parentObj.myOwnRawDataObj[dataKey]; // dataKey是有必要的,必须知道是哪个Table
  1004. // 计量需要重写
  1005. if (dtObj) {
  1006. const dtData = getActDataArr(dtObj);
  1007. for (let i = 0; i < dtData.length; i++) {
  1008. if (dftVal !== null && dftVal !== undefined) {
  1009. rst.push(dftVal)
  1010. } else rst.push('');
  1011. }
  1012. }
  1013. return rst;
  1014. }
  1015. function ext_translateConst(constName, constDtlName, destConstKeyValArr) {
  1016. const rst = [];
  1017. if (destConstKeyValArr instanceof Array && TRANSLATE_CONST[constName] && TRANSLATE_CONST[constName][constDtlName]) {
  1018. for (const keyV of destConstKeyValArr) {
  1019. const idx = TRANSLATE_CONST[constName][constDtlName].keys.indexOf(keyV);
  1020. if (idx >= 0) {
  1021. rst.push(TRANSLATE_CONST[constName][constDtlName].values[idx]);
  1022. } else {
  1023. rst.push(null);
  1024. }
  1025. }
  1026. }
  1027. return rst;
  1028. }
  1029. function ext_getPropertyByForeignId(foreignIdVal, adHocIdKey, propKey, dftValIfNotFound) {
  1030. const rst = [];
  1031. // 计量需要重写
  1032. return rst;
  1033. }
  1034. function getActDataArr(dtObj) {
  1035. let rst = [];
  1036. if (dtObj) {
  1037. if (dtObj instanceof Array) {
  1038. rst = rst.concat(dtObj);
  1039. } else {
  1040. rst.push(dtObj);
  1041. }
  1042. }
  1043. return rst;
  1044. }
  1045. function replaceActDataArr(dtObj, newArr) {
  1046. if (dtObj.moduleName === 'projectGLJ') {
  1047. delete dtObj.data.gljList;
  1048. dtObj.data.gljList = newArr;
  1049. } else {
  1050. delete dtObj.data;
  1051. dtObj.data = newArr;
  1052. }
  1053. }
  1054. function pri_push_property(propKey, doc, rst) {
  1055. if (propKey instanceof Array) {
  1056. // 备注:这里的key数组表示取value的优先级
  1057. for (let pi = 0; pi < propKey.length; pi++) {
  1058. if (doc.hasOwnProperty('property')) {
  1059. if (doc['property'].hasOwnProperty(propKey[pi])) {
  1060. rst.push(doc['property'][propKey[pi]]);
  1061. break;
  1062. }
  1063. } else if (doc.hasOwnProperty(propKey[pi])) {
  1064. rst.push(doc[propKey[pi]]);
  1065. break;
  1066. } else {
  1067. const lenBefore = rst.length;
  1068. getDeepProperty(propKey[pi], doc, rst);
  1069. if (rst.length === (lenBefore + 1)) {
  1070. if (rst[lenBefore] !== null && rst[lenBefore] !== undefined && rst[lenBefore] !== '') {
  1071. break;
  1072. } else {
  1073. rst.splice(-1, 1); // 删除末尾一条数据,给后面留空间
  1074. }
  1075. }
  1076. }
  1077. if (pi === propKey.length - 1) rst.push('');
  1078. }
  1079. } else {
  1080. if (doc.hasOwnProperty('property') && doc['property'].hasOwnProperty(propKey)) {
  1081. rst.push(doc['property'][propKey]);
  1082. } else if (doc.hasOwnProperty(propKey)) {
  1083. rst.push(doc[propKey]);
  1084. } else {
  1085. getDeepProperty(propKey, doc, rst);
  1086. }
  1087. }
  1088. }
  1089. // export default Rpt_Data_Extractor;
  1090. module.exports = Rpt_Data_Extractor;