rpt_format_setup.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. const reportFormatSetupObj = {
  2. treeObj: null,
  3. templateObj: {},
  4. canvas: null,
  5. fieldParamOptions: null,
  6. maxFieldID: -1,
  7. onCheck: (event, treeId, treeNode) => {
  8. //
  9. },
  10. onClick: (event,treeId,treeNode) => {
  11. const me = reportFormatSetupObj;
  12. if (treeNode.nodeType === RT.NodeType.TEMPLATE) {
  13. me.initialize(treeNode);
  14. }
  15. },
  16. onDeleteInfo: (dom) => {
  17. // 删除表眉、表脚项
  18. // console.log(dom.parentElement.parentElement);
  19. $(dom.parentElement.parentElement).remove();
  20. },
  21. onAddInfo: (dom, lv) => {
  22. // 增加表眉、表脚细项
  23. const me = reportFormatSetupObj;
  24. const domStrs = [];
  25. domStrs.push('<tr class="text-center">');
  26. domStrs.push('<td></td>');
  27. domStrs.push(`<td>${me._createTypeSelection(0)}</td>`);
  28. domStrs.push(`<td class="text-left"><input class="form-control form-control-sm" value="" type="text"></td>`);
  29. domStrs.push(`<td class="text-left"><input class="form-control form-control-sm" value="0" type="text"></td>`);
  30. domStrs.push(`<td class="text-left"><input class="form-control form-control-sm" value="0" type="text"></td>`);
  31. domStrs.push(`<td class="text-left"><input class="form-control form-control-sm" value="" type="text"></td>`);
  32. domStrs.push(`<td class="text-left"><input class="form-control form-control-sm" value="" type="text"></td>`);
  33. domStrs.push('<td><a href="#" onclick="reportFormatSetupObj.onDeleteInfo(this)" class="text-danger mr-2" title="删除">删除</a></td>');
  34. domStrs.push('</tr>');
  35. $(dom.parentElement.parentElement).after(domStrs.join(''));
  36. },
  37. onAddLvInfo: (dom) => {
  38. // 增加表眉、表脚层次项
  39. console.log(dom);
  40. let maxCnt = 0;
  41. // for (const td of dom.parentElement.parentElement.nextElementSibling.children[0].children[1].children) {
  42. if (dom.parentElement.parentElement.parentElement.nextElementSibling.children.length > 0) {
  43. for (const td of dom.parentElement.parentElement.parentElement.nextElementSibling.children[0].children[1].children) {
  44. if (td.cells[0].innerText !== '') {
  45. const lv = parseInt(td.cells[0].innerText) || 0;
  46. if (lv > maxCnt) maxCnt = lv;
  47. }
  48. }
  49. }
  50. // dom.parentElement.parentElement.nextElementSibling.children[0].children[1]
  51. const lvDtl = [];
  52. lvDtl.push('<tr class="text-center">');
  53. lvDtl.push(`<td>${maxCnt + 1}</td>`);
  54. lvDtl.push('<td></td>');
  55. lvDtl.push('<td></td>');
  56. lvDtl.push('<td></td>');
  57. lvDtl.push('<td></td>');
  58. lvDtl.push('<td></td>');
  59. lvDtl.push('<td></td>');
  60. lvDtl.push('<td><a href="#" onclick="reportFormatSetupObj.onAddInfo(this)" class="text-primary mr-2" title="新增插入子项">新增</a></td>');
  61. lvDtl.push('</tr>');
  62. $(dom.parentElement.parentElement.parentElement.nextElementSibling.children[0].children[1]).append(lvDtl.join(''));
  63. },
  64. onTypeChange: (dom) => {
  65. const me = reportFormatSetupObj;
  66. console.log(dom);
  67. // 根据新选项清理、初始化
  68. if (dom.selectedIndex === 0) {
  69. // 文本
  70. $(dom.parentElement.nextSibling).html('<input class="form-control form-control-sm" value="" type="text">');
  71. dom.parentElement.nextSibling.nextSibling.nextSibling.nextSibling.children[0].value = '';
  72. dom.parentElement.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.children[0].value = '';
  73. } else {
  74. // 指标
  75. const curNodes = me.treeObj.getSelectedNodes();
  76. if (curNodes.length > 0) {
  77. const rptTemplate = me.templateObj[`${curNodes[0].ID}`];
  78. if (rptTemplate) {
  79. $(dom.parentElement.nextSibling).html(`${me._createSelectionFields(-1, 5010)}`);
  80. dom.parentElement.nextSibling.nextSibling.nextSibling.nextSibling.children[0].value = '';
  81. dom.parentElement.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.children[0].value = '';
  82. }
  83. }
  84. }
  85. },
  86. onAddSignature: (dom) => {
  87. const me = reportFormatSetupObj;
  88. me.maxFieldID++;
  89. const newSignature = [];
  90. newSignature.push('<li class="d-flex justify-content-start align-items-center mb-3">');
  91. newSignature.push(`<span class="col-auto"><input class="form-control form-control-sm" FID="${me.maxFieldID}" value="" type="text"></span>`);
  92. newSignature.push('<span><a href="#" onclick="reportFormatSetupObj.onRemoveSignature(this)" class="btn-sm text-danger px-1" title="移除"><i class="fa fa-remove"></i></a></span>');
  93. newSignature.push('</li>');
  94. $(dom.parentElement).before(newSignature.join(''));
  95. },
  96. onRemoveSignature: (dom) => {
  97. $(dom.parentElement.parentElement).remove();
  98. },
  99. initialize: (rptNode) => {
  100. const me = reportFormatSetupObj;
  101. me.canvas = document.getElementById("rptSetupPreviewCanvas");
  102. // 1. 先清理
  103. me.clearTplProperties();
  104. // 2. 再加表标题、表眉、表脚、电子签名内容
  105. const params = { rpt_tpl_id: rptNode.refId };
  106. const url = '/report_api/getReportTemplate';
  107. $.bootstrapLoading.start();
  108. CommonAjax.postXsrfEx(url, params, 300000, true, getCookie('csrfToken_j'),
  109. async function(result){
  110. console.log(result);
  111. me.templateObj[`${rptNode.refId}`] = result.data;
  112. if (result.data['主信息']['打印页面_信息']['方向'] === 'PORTRAIT') {
  113. me.canvas.height = 1150;
  114. me.canvas.width = 820;
  115. } else {
  116. me.canvas.height = 820;
  117. me.canvas.width = 1150;
  118. }
  119. if (result.data['主信息']['打印页面_信息']['页规格'] === 'A3') {
  120. me.canvas.height = me.canvas.height * 1.414;
  121. me.canvas.width = me.canvas.width * 1.414;
  122. }
  123. me.fieldParamOptions = me.initialSelectionFields(result.data);
  124. me.maxFieldID = me._getTheMaxFieldID(result.data);
  125. me.initialTitle(result.data);
  126. me.initialHeader(result.data);
  127. me.initialFooter(result.data);
  128. me.initialSignature(result.data);
  129. $.bootstrapLoading.end();
  130. }, function(err){
  131. console.log(err);
  132. $.bootstrapLoading.end();
  133. }, function(ex){
  134. console.log(ex);
  135. $.bootstrapLoading.end();
  136. }
  137. );
  138. },
  139. clearTplProperties: () => {
  140. // 表眉
  141. $("#rpt_header_div").empty();
  142. // const str1 = '<div>表眉</div><div><input id="header_band_height_input" class="form-control form-control-sm" value="" type="text"></input></div><div><a href="#" onclick="reportFormatSetupObj.onAddLvInfo(this)" class="btn btn-sm btn-light text-primary">新增行</a></div>';
  143. const str1Arr = [];
  144. str1Arr.push('<div>表眉');
  145. str1Arr.push('</div>');
  146. str1Arr.push('<div>');
  147. str1Arr.push('<div>默认行高: ');
  148. str1Arr.push('<input id="header_band_height_input" value="" type="number" step="0.1" width="10"></input>');
  149. str1Arr.push('<a href="#" onclick="reportFormatSetupObj.onAddLvInfo(this)" class="btn btn-sm btn-light text-primary">新增行</a>');
  150. str1Arr.push('</div>');
  151. str1Arr.push('</div>');
  152. const str1 = str1Arr.join('');
  153. $("#rpt_header_div").append(str1);
  154. $("#rpt_header_table_div").empty();
  155. // 表脚
  156. $("#rpt_footer_div").empty();
  157. // const str2 = '<div>表脚</div><div><input id="footer_band_height_input" class="form-control form-control-sm" value="" type="text"></input></div><div><a href="#" onclick="reportFormatSetupObj.onAddLvInfo(this)" class="btn btn-sm btn-light text-primary">新增行</a></div>';
  158. const str2Arr = [];
  159. str2Arr.push('<div>表脚');
  160. str2Arr.push('</div>');
  161. str2Arr.push('<div>');
  162. str2Arr.push('<div>默认行高: ');
  163. str2Arr.push('<input id="footer_band_height_input" value="" type="number" step="0.1" width="10"></input>');
  164. str2Arr.push('<a href="#" onclick="reportFormatSetupObj.onAddLvInfo(this)" class="btn btn-sm btn-light text-primary">新增行</a>');
  165. str2Arr.push('</div>');
  166. str2Arr.push('</div>');
  167. const str2 = str2Arr.join('');
  168. $("#rpt_footer_div").append(str2);
  169. $("#rpt_footer_table_div").empty();
  170. // 表标题
  171. $("#rpt_title_input")[0].value = '';
  172. // 电子签名
  173. // signature_ul_list
  174. $("#signature_ul_list").empty();
  175. $("#signature_ul_list").append('<li class="pl-3" id="signature_li_list"><a href="#" onclick="reportFormatSetupObj.onAddSignature(this)"><i class="fa fa-plus"></i> 添加新签字人</a></li>');
  176. },
  177. initialHeader: (rptTpl) => {
  178. const me = reportFormatSetupObj;
  179. const bandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'HeaderBand');
  180. if (bandInfo) {
  181. const posArr = me._checkLevelInfo(bandInfo);
  182. const html = me._buildHeaderFooterHTML(rptTpl, bandInfo, posArr);
  183. const actBand = rptTpl['布局框_集合'].find(band => band.Name === 'HeaderBand');
  184. const dftRowHeight = +(actBand.Height || 0.6) / (posArr.length || 1);
  185. $("#header_band_height_input")[0].value = dftRowHeight;
  186. // console.log(html);
  187. // $("#rpt_header_parent_div").empty();
  188. $("#rpt_header_table_div").append(html.join(''));
  189. // rpt_header_div
  190. }
  191. },
  192. initialFooter: (rptTpl) => {
  193. const me = reportFormatSetupObj;
  194. const bandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'FooterBand');
  195. if (bandInfo) {
  196. const posArr = me._checkLevelInfo(bandInfo);
  197. const html = me._buildHeaderFooterHTML(rptTpl, bandInfo, posArr);
  198. const actBand = rptTpl['布局框_集合'].find(band => band.Name === 'FooterBand');
  199. const dftRowHeight = +(actBand.Height || 0.6) / (posArr.length || 1);
  200. $("#footer_band_height_input")[0].value = dftRowHeight;
  201. // console.log(html);
  202. // $("#rpt_header_parent_div").empty();
  203. $("#rpt_footer_table_div").append(html.join(''));
  204. // rpt_header_div
  205. }
  206. //
  207. },
  208. initialTitle: (rptTpl) => {
  209. const me = reportFormatSetupObj;
  210. $("#rpt_title_input")[0].value = me._getTitle(rptTpl);
  211. const curNodes = me.treeObj.getSelectedNodes();
  212. if (curNodes.length > 0) {
  213. $("#rename_rpt_confirm")[0].innerText=`确认更新报表模板「${curNodes[0].name}」?`;
  214. }
  215. },
  216. initialSignature: (rptTpl) => {
  217. const jDom = $("#signature_li_list");
  218. if (rptTpl['电子签名离散指标_集合'] && rptTpl['电子签名离散指标_集合'].length > 0) {
  219. for (const disF of rptTpl['电子签名离散指标_集合']) {
  220. const newSignature = [];
  221. newSignature.push('<li class="d-flex justify-content-start align-items-center mb-3">');
  222. newSignature.push(`<span class="col-auto"><input class="form-control form-control-sm" FID="${disF.ID}" value="${disF.Name}" type="text"></span>`);
  223. newSignature.push('<span><a href="#" onclick="reportFormatSetupObj.onRemoveSignature(this)" class="btn-sm text-danger px-1" title="移除"><i class="fa fa-remove"></i></a></span>');
  224. newSignature.push('</li>');
  225. jDom.before(newSignature.join(''));
  226. }
  227. }
  228. },
  229. _getTitle: (rptTpl) => {
  230. const me = reportFormatSetupObj;
  231. let rst = '';
  232. const bandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'TitleBand');
  233. if (bandInfo && bandInfo.text_s) {
  234. const titleTxt = bandInfo.text_s.find(item => item.font === 'ReportTitle_Main');
  235. if (titleTxt) {
  236. rst = titleTxt.Label;
  237. } else {
  238. rst = bandInfo.text_s[0].Label;
  239. }
  240. }
  241. return rst;
  242. },
  243. _setTitle: (rptTpl, newTitle) => {
  244. const me = reportFormatSetupObj;
  245. const bandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'TitleBand');
  246. if (bandInfo && bandInfo.text_s) {
  247. const titleTxt = bandInfo.text_s.find(item => item.font === 'ReportTitle_Main');
  248. if (titleTxt) {
  249. titleTxt.Label = newTitle;
  250. } else {
  251. bandInfo.text_s[0].Label = newTitle;
  252. }
  253. }
  254. },
  255. _getRightInfoObj: (rptTpl) => {
  256. let rst = null;
  257. if (rptTpl) {
  258. if (rptTpl['流水式表_信息']) {
  259. rst = rptTpl['流水式表_信息'];
  260. } else if (rptTpl['账单式表_信息']) {
  261. rst = rptTpl['账单式表_信息'];
  262. } else if (rptTpl['交叉表_信息']) {
  263. rst = rptTpl['交叉表_信息'];
  264. }
  265. }
  266. return rst;
  267. },
  268. _getRightBandInfoObj: (infoObj, bandName) => {
  269. let rst = null;
  270. if (infoObj) {
  271. for (let info of infoObj['离散信息']) {
  272. if (info['BandName'] === bandName) {
  273. rst = info;
  274. break;
  275. }
  276. }
  277. }
  278. return rst;
  279. },
  280. _checkLevelInfo: (bandInfo) => {
  281. let rst = [];
  282. if (bandInfo) {
  283. if (bandInfo.discrete_field_s) {
  284. for (const field of bandInfo.discrete_field_s) {
  285. const bt = +field.area.Bottom;
  286. if (!rst.includes(bt)) rst.push(bt);
  287. }
  288. }
  289. if (bandInfo.text_s) {
  290. for (const txt of bandInfo.text_s) {
  291. const bt = +txt.area.Bottom;
  292. if (!rst.includes(bt)) rst.push(bt);
  293. }
  294. }
  295. }
  296. return rst;
  297. },
  298. _createTypeSelection: (dftSelection = 0) => {
  299. const rst = [];
  300. rst.push('<select class="form-control form-control-sm" onchange="reportFormatSetupObj.onTypeChange(this)">');
  301. rst.push(`<option${dftSelection === 0 ? ' selected' : ''}>文本</option>`);
  302. rst.push(`<option${dftSelection !== 0 ? ' selected' : ''}>指标</option>`);
  303. rst.push('</select>');
  304. return rst.join('');
  305. },
  306. initialSelectionFields: (rptTpl) => {
  307. // 这里统一收集可选指标范围(有默认范围 + 报表本身特别的指标)
  308. const me = reportFormatSetupObj;
  309. const rst = { fields_collection: [], params_collection: [] };
  310. for (const param of rptTpl['离散参数_集合']) {
  311. rst.params_collection.push({ PID: +param.ID, name: param.Name, dftValue: param.Default_Value || '' });
  312. }
  313. for (const fd of rptTpl['指标_数据_映射']['离散指标_集合']) {
  314. rst.fields_collection.push({ FID: +fd.ID, name: fd.Name });
  315. }
  316. const collectAdhocFields = (hfBandInfo) => {
  317. if (hfBandInfo && hfBandInfo.discrete_field_s) {
  318. for (const field of hfBandInfo.discrete_field_s) {
  319. if (!field.ParamID) {
  320. const selField = rst.fields_collection.find(item => item.FID === +field.FieldID);
  321. if (!selField) {
  322. const ahocSelField = me._scanField(rptTpl, field.FieldID);
  323. rst.fields_collection.push({ FID: +ahocSelField.ID, name: ahocSelField.Name });
  324. }
  325. }
  326. }
  327. }
  328. };
  329. const headerBandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'HeaderBand');
  330. collectAdhocFields(headerBandInfo);
  331. const footerBandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'FooterBand');
  332. collectAdhocFields(footerBandInfo);
  333. return rst;
  334. },
  335. _getTheMaxFieldID: (rptTpl) => {
  336. let rst = -1;
  337. if (rptTpl['无映射离散指标_集合'] && rptTpl['无映射离散指标_集合'].length > 0) {
  338. rptTpl['无映射离散指标_集合'].forEach((disF) => {
  339. if (+(disF.ID || -1) > rst) rst = +disF.ID;
  340. });
  341. }
  342. if (rptTpl['电子签名离散指标_集合'] && rptTpl['电子签名离散指标_集合'].length > 0) {
  343. rptTpl['电子签名离散指标_集合'].forEach((disF) => {
  344. if (+(disF.ID || -1) > rst) rst = +disF.ID;
  345. });
  346. }
  347. if (rptTpl['动态日期离散参数_集合'] && rptTpl['动态日期离散参数_集合'].length > 0) {
  348. rptTpl['动态日期离散参数_集合'].forEach((disF) => {
  349. if (+(disF.ID || -1) > rst) rst = +disF.ID;
  350. });
  351. }
  352. if (rptTpl['电子签名审核意见指标_集合'] && rptTpl['电子签名审核意见指标_集合'].length > 0) {
  353. rptTpl['电子签名审核意见指标_集合'].forEach((disF) => {
  354. if (+(disF.ID || -1) > rst) rst = +disF.ID;
  355. });
  356. }
  357. return rst;
  358. },
  359. _createSelectionFields_BK: (rptTpl, currentFieldID, ParamID) => {
  360. const me = reportFormatSetupObj;
  361. const rst = [];
  362. let hasSelected = false;
  363. rst.push('<select class="form-control form-control-sm">');
  364. for (const fd of rptTpl['指标_数据_映射']['离散指标_集合']) {
  365. if (!hasSelected) {
  366. hasSelected = fd.ID === currentFieldID;
  367. }
  368. const selectedStr = fd.ID === currentFieldID ? ' selected' : '';
  369. rst.push(`<option${selectedStr} FID="${fd.ID}">${fd.Name}</option>`);
  370. }
  371. if (!hasSelected) {
  372. // 如果没有在选项中,那表示是一个额外的指标(可能在: a. '电子签名离散指标_集合' b. '无映射离散指标_集合'中 etc...),需要在模板中全扫描一把
  373. // 有2种情况,一种是离散的指标,另一种是特殊参数(页码)
  374. if (ParamID) {
  375. for (const pd of rptTpl['离散参数_集合']) {
  376. if (`${pd.ID}` === `${ParamID}`) {
  377. rst.push(`<option selected PID="${ParamID}">${pd.Name}</option>`);
  378. break;
  379. }
  380. }
  381. } else {
  382. const selField = me._scanField(rptTpl, currentFieldID);
  383. if (selField) {
  384. rst.push(`<option selected FID="${currentFieldID}">${selField.Name}</option>`);
  385. }
  386. }
  387. }
  388. rst.push('</select>');
  389. return rst.join('');
  390. },
  391. _createSelectionFields: (currentFieldID, ParamID) => {
  392. const me = reportFormatSetupObj;
  393. const rst = [];
  394. let hasSelected = false;
  395. rst.push('<select class="form-control form-control-sm">');
  396. for (const fd of reportFormatSetupObj.fieldParamOptions.fields_collection) {
  397. const selectedStr = `${fd.FID}` === `${currentFieldID}` ? ' selected' : '';
  398. rst.push(`<option${selectedStr} FID="${fd.FID}">${fd.name}</option>`);
  399. }
  400. for (const pd of reportFormatSetupObj.fieldParamOptions.params_collection) {
  401. const selectedStr = `${pd.PID}` === `${ParamID}` ? ' selected' : '';
  402. rst.push(`<option${selectedStr} PID="${pd.PID}">${pd.name}</option>`);
  403. }
  404. rst.push('</select>');
  405. return rst.join('');
  406. },
  407. _scanField: (rptTpl, curFieldId) => {
  408. let rst = null;
  409. rst = rptTpl['无映射离散指标_集合'].find(item => item.ID === curFieldId);
  410. if (!rst) rst = rptTpl['电子签名离散指标_集合'].find(item => `${item.ID}` === `${curFieldId}`);
  411. if (!rst) rst = rptTpl['动态日期离散参数_集合'].find(item => `${item.ID}` === `${curFieldId}`);
  412. if (!rst) rst = rptTpl['电子签名审核意见指标_集合'].find(item => `${item.ID}` === `${curFieldId}`);
  413. if (!rst) rst = rptTpl['指标_数据_映射']['从数据指标_集合'].find(item => `${item.ID}` === `${curFieldId}`);
  414. if (!rst) rst = rptTpl['指标_数据_映射']['主数据指标_集合'].find(item => `${item.ID}` === `${curFieldId}`);
  415. return rst;
  416. },
  417. _buildHeaderFooterHTML: (rptTpl, hfBandInfo, posArr) => {
  418. const me = reportFormatSetupObj;
  419. const rst = [];
  420. if (hfBandInfo && posArr.length > 0) {
  421. // 1. 增加一些必要html
  422. rst.push(' <table class="table table-bordered">')
  423. rst.push(' <thead>');
  424. rst.push(' <tr>');
  425. rst.push(' <th width="5%" style="text-align: center;">行号</th>');
  426. rst.push(' <th width="10%" style="text-align: center;">类型</th>');
  427. rst.push(' <th width="20%" style="text-align: center;">值</th>');
  428. rst.push(' <th width="10%" style="text-align: center;">左位置</th>');
  429. rst.push(' <th width="10%" style="text-align: center;">右位置</th>');
  430. rst.push(' <th width="15%" style="text-align: center;">前缀</th>');
  431. rst.push(' <th width="15%" style="text-align: center;">后缀</th>');
  432. rst.push(' <th width="15%" style="text-align: center;">操作</th>');
  433. rst.push(' </tr>');
  434. rst.push(' </thead>');
  435. rst.push(' <tbody>')
  436. // --------
  437. const lvs = [];
  438. for (let idx = 0; idx < posArr.length; idx++) {
  439. const lvDtl = [];
  440. lvDtl.push('<tr class="text-center">');
  441. lvDtl.push(`<td>${idx + 1}</td>`);
  442. lvDtl.push('<td></td>');
  443. lvDtl.push('<td></td>');
  444. lvDtl.push('<td></td>');
  445. lvDtl.push('<td></td>');
  446. lvDtl.push('<td></td>');
  447. lvDtl.push('<td></td>');
  448. lvDtl.push('<td><a href="#" onclick="reportFormatSetupObj.onAddInfo(this)" class="text-primary mr-2" title="新增插入子项">新增</a></td>');
  449. lvDtl.push('</tr>');
  450. lvs.push(lvDtl);
  451. }
  452. if (hfBandInfo.text_s) {
  453. for (const txt of hfBandInfo.text_s) {
  454. const bt = +txt.area.Bottom;
  455. const btIdx = posArr.indexOf(bt);
  456. if (btIdx >= 0) {
  457. lvs[btIdx].push('<tr class="text-center">');
  458. lvs[btIdx].push('<td></td>');
  459. lvs[btIdx].push(`<td>${me._createTypeSelection(0)}</td>`);
  460. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${txt.Label || ''}" type="text"></td>`);
  461. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${txt.area.Left || '0'}" type="text"></td>`);
  462. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${txt.area.Right || '0'}" type="text"></td>`);
  463. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="" type="text"></td>`);
  464. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="" type="text"></td>`);
  465. // lvs[btIdx].push('<td></td>');
  466. // lvs[btIdx].push('<td></td>');
  467. lvs[btIdx].push('<td><a href="#" onclick="reportFormatSetupObj.onDeleteInfo(this)" class="text-danger mr-2" title="删除">删除</a></td>');
  468. lvs[btIdx].push('</tr>');
  469. }
  470. }
  471. }
  472. if (hfBandInfo.discrete_field_s) {
  473. for (const field of hfBandInfo.discrete_field_s) {
  474. const bt = +field.area.Bottom;
  475. const btIdx = posArr.indexOf(bt);
  476. if (btIdx >= 0) {
  477. lvs[btIdx].push('<tr class="text-center">');
  478. lvs[btIdx].push('<td></td>');
  479. lvs[btIdx].push(`<td>${me._createTypeSelection(1)}</td>`);
  480. // lvs[btIdx].push(`<td>${me._createSelectionFields_BK(rptTpl, field.FieldID, field.ParamID)}</td>`);
  481. lvs[btIdx].push(`<td>${me._createSelectionFields(field.FieldID, field.ParamID)}</td>`);
  482. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${field.area.Left || '0'}" type="text"></td>`);
  483. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${field.area.Right || '0'}" type="text"></td>`);
  484. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${field.Prefix || ''}" type="text"></td>`);
  485. lvs[btIdx].push(`<td class="text-left"><input class="form-control form-control-sm" value="${field.Suffix || ''}" type="text"></td>`);
  486. lvs[btIdx].push('<td><a href="#" onclick="reportFormatSetupObj.onDeleteInfo(this)" class="text-danger mr-2" title="删除">删除</a></td>');
  487. lvs[btIdx].push('</tr>');
  488. }
  489. }
  490. }
  491. //...
  492. for (const lv of lvs) {
  493. rst.push(...lv);
  494. }
  495. rst.push(' </tbody>')
  496. rst.push(' </table>')
  497. }
  498. return rst;
  499. },
  500. updateReportTemplate: () => {
  501. const me = reportFormatSetupObj;
  502. const rptTemplate = me._prepareReportTemplate();
  503. const curNodes = me.treeObj.getSelectedNodes();
  504. if (rptTemplate && curNodes.length > 0) {
  505. const params = { tplId: curNodes[0].ID, tplName: curNodes[0].name, tplObj: JSON.stringify(rptTemplate) };
  506. const url = '/report_api/updateReportTemplate';
  507. $.bootstrapLoading.start();
  508. CommonAjax.postXsrfEx(url, params, 300000, true, getCookie('csrfToken_j'),
  509. async function(result){
  510. console.log(result);
  511. $.bootstrapLoading.end();
  512. }, function(err){
  513. console.log(err);
  514. $.bootstrapLoading.end();
  515. }, function(ex){
  516. console.log(ex);
  517. $.bootstrapLoading.end();
  518. }
  519. );
  520. }
  521. },
  522. preview: () => {
  523. // alert('hi');
  524. const me = reportFormatSetupObj;
  525. const rptTemplate = me._prepareReportTemplate();
  526. if (rptTemplate) {
  527. const params = { tplObj: JSON.stringify(rptTemplate) };
  528. const url = '/report_api/getPreviewReport';
  529. $.bootstrapLoading.start();
  530. CommonAjax.postXsrfEx(url, params, 300000, true, getCookie('csrfToken_j'),
  531. async function(result){
  532. // console.log(result);
  533. JpcCanvasOutput.cleanCanvas(me.canvas);
  534. JpcCanvasOutput.drawPageBorder(result.pageRst, me.canvas, getScreenDPI());
  535. JpcCanvasOutput.highlightConflictArea(result.pageRst, 1);
  536. JpcCanvasOutput.drawToCanvas(result.pageRst, me.canvas, 1);
  537. $.bootstrapLoading.end();
  538. }, function(err){
  539. console.log(err);
  540. $.bootstrapLoading.end();
  541. }, function(ex){
  542. console.log(ex);
  543. $.bootstrapLoading.end();
  544. }
  545. );
  546. }
  547. },
  548. previewSign: () => {
  549. const me = reportFormatSetupObj;
  550. $("#dummy_sign_preview").empty();
  551. const signs = [];
  552. const domObj = $("#signature_ul_list")[0];
  553. for (let dIdx = 0; dIdx < domObj.children.length - 1; dIdx++) {
  554. const signName = domObj.children[dIdx].children[0].children[0].value; // 电子签名名称
  555. signs.push('<div class="form-group row">');
  556. signs.push(`<label for="staticEmail" class="col-sm-3 col-form-label pr-0">${signName || ''}</label>`);
  557. signs.push('<div class="col-sm-9">');
  558. signs.push('<ul class="list-group">');
  559. signs.push('<li class="list-group-item"><a class="text-muted"><i class="fa fa-plus"></i> 添加签字</a></li>');
  560. signs.push('</ul>');
  561. signs.push('</div>');
  562. signs.push('</div>');
  563. }
  564. $("#dummy_sign_preview").append(signs.join(''));
  565. },
  566. _prepareReportTemplate: () => {
  567. let rst = null;
  568. const me = reportFormatSetupObj;
  569. const curNodes = me.treeObj.getSelectedNodes();
  570. if (curNodes.length > 0) {
  571. const headers = me._createCommonCollctInfo('#rpt_header_table_div');
  572. const footers = me._createCommonCollctInfo('#rpt_footer_table_div');
  573. const signatures = me._createSignatureInfo(me.templateObj[`${curNodes[0].ID}`]);
  574. const rptTemplate = me.templateObj[`${curNodes[0].ID}`];
  575. if (rptTemplate) {
  576. me._setupTemplate(rptTemplate, headers, footers, signatures);
  577. rst = rptTemplate;
  578. }
  579. }
  580. return rst;
  581. },
  582. _createCommonCollctInfo: (containerId) => {
  583. let lvCnt = 0;
  584. const rst = { texts: [], fields: [], levels: 0 };
  585. const createAreaFromDom = (firstDom, lv) => {
  586. const rst = { Top: lv, Left: 0, Right: 0, Bottom: lv + 1, H_CalculationType: "percentage", V_CalculationType: "percentage" };
  587. rst.Left = firstDom.cells[3].childNodes[0].value || 0;
  588. rst.Right = firstDom.cells[4].childNodes[0].value || 0;
  589. return rst;
  590. };
  591. const ParamDftValMap = { '5010': '第 X 页', '5011': '共 X 页' };
  592. const domObj = $(containerId);
  593. if (domObj[0].childNodes.length > 0) {
  594. for (let idx = 0; idx < domObj[0].childNodes[1].childNodes[3].childNodes.length; idx++) {
  595. const hDom = domObj[0].childNodes[1].childNodes[3].childNodes[idx];
  596. if (hDom.innerText && hDom.innerText.includes('新增')) {
  597. let dtlCnt = 0;
  598. for (let idxN = idx + 1; idxN < domObj[0].childNodes[1].childNodes[3].childNodes.length; idxN++) {
  599. // 开始创建文本对象或指标对象
  600. const hnDom = domObj[0].childNodes[1].childNodes[3].childNodes[idxN];
  601. if (hnDom.innerText && !hnDom.innerText.includes('新增')) {
  602. dtlCnt++;
  603. const areaObj = createAreaFromDom(hnDom, lvCnt);
  604. if (hnDom.cells[1].childNodes[0][0].selected) {
  605. // 创建文本对象
  606. const txtObj = { area: areaObj, font: 'Header', control: 'Header', style: 'Default_None', Label: ''};
  607. txtObj.Label = hnDom.cells[2].childNodes[0].value || '';
  608. rst.texts.push(txtObj);
  609. } else {
  610. // 创建指标对象
  611. const fieldObj = { area: areaObj, font: 'Header', control: 'Header', style: 'Default_None', Prefix: '', Suffix: ''};
  612. fieldObj.Prefix = hnDom.cells[5].childNodes[0].value || '';
  613. fieldObj.Suffix = hnDom.cells[6].childNodes[0].value || '';
  614. for (const fIdOpt of hnDom.cells[2].childNodes[0]) {
  615. if (fIdOpt.selected) {
  616. if (fIdOpt.attributes['fid']) {
  617. fieldObj.FieldID = +fIdOpt.attributes[fIdOpt.attributes.length - 1].nodeValue;
  618. } else {
  619. fieldObj.ParamID = fIdOpt.attributes[fIdOpt.attributes.length - 1].nodeValue;
  620. fieldObj.Default_Value = ParamDftValMap[fieldObj.ParamID] || '';
  621. }
  622. break;
  623. }
  624. }
  625. rst.fields.push(fieldObj);
  626. }
  627. } else {
  628. break;
  629. }
  630. }
  631. if (dtlCnt > 0) lvCnt++; // 有子项的才会被统计进来
  632. // lvCnt++; // 不能无条件的统计增加层次
  633. }
  634. }
  635. }
  636. if (lvCnt > 0) {
  637. // 所有rst的text、field的纵坐标都要重新整理一遍
  638. rst.levels = lvCnt;
  639. const lvH = +(100 / lvCnt).toFixed(3);
  640. for (const txt of rst.texts) {
  641. txt.area.Top = lvH * txt.area.Top;
  642. txt.area.Bottom = lvH * txt.area.Bottom;
  643. }
  644. for (const fld of rst.fields) {
  645. fld.area.Top = lvH * fld.area.Top;
  646. fld.area.Bottom = lvH * fld.area.Bottom;
  647. }
  648. }
  649. return rst;
  650. },
  651. _createSignatureInfo: (rptTpl) => {
  652. const me = reportFormatSetupObj;
  653. const rst = [[], [], []]; // 电子签名、日期、审核意见 三件套
  654. const domObj = $("#signature_ul_list")[0];
  655. const createReplaceField = (fid, name) => {
  656. return { ID: +fid, Name: name, DataType: 'string', Default_Value: '' };
  657. };
  658. for (let dIdx = 0; dIdx < domObj.children.length - 1; dIdx++) {
  659. const signName = domObj.children[dIdx].children[0].children[0].value; // 电子签名名称
  660. const signFId = +domObj.children[dIdx].children[0].children[0].attributes[1].value; // 指标ID
  661. rst[0].push(createReplaceField(signFId, signName));
  662. let dftFieldID = 0;
  663. const assField1 = rptTpl['动态日期离散参数_集合'].find(disF => disF.Name === signName + '_签字日期')
  664. if (!assField1) {
  665. me.maxFieldID++;
  666. dftFieldID = me.maxFieldID;
  667. } else {
  668. dftFieldID = +assField1.ID;
  669. }
  670. rst[1].push(createReplaceField(dftFieldID, signName + '_签字日期'));
  671. const assField2 = rptTpl['电子签名审核意见指标_集合'].find(disF => disF.Name === signName + '_审核意见')
  672. if (!assField2) {
  673. me.maxFieldID++;
  674. dftFieldID = me.maxFieldID;
  675. } else {
  676. dftFieldID = +assField2.ID;
  677. }
  678. rst[2].push(createReplaceField(dftFieldID, signName + '_审核意见'));
  679. }
  680. return rst;
  681. },
  682. _setupTemplate: (rptTpl, headersInfo, footersInfo, signatureInfo = null) => {
  683. const me = reportFormatSetupObj;
  684. me._setTitle(rptTpl, $("#rpt_title_input")[0].value);
  685. const headerBandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'HeaderBand');
  686. if (headerBandInfo) {
  687. const headerBand = rptTpl['布局框_集合'].find(item => item.Name === 'HeaderBand');
  688. // 1. 高度
  689. if (headerBand) {
  690. let dftHeight = $("#header_band_height_input")[0].value || 0.6;
  691. if (dftHeight === '') dftHeight = 0.6;
  692. headerBand.Height = dftHeight * headersInfo.levels;
  693. }
  694. // 2.
  695. headerBandInfo.text_s = headersInfo.texts;
  696. headerBandInfo.discrete_field_s = headersInfo.fields;
  697. }
  698. const footerBandInfo = me._getRightBandInfoObj(me._getRightInfoObj(rptTpl), 'FooterBand');
  699. if (footerBandInfo) {
  700. const footerBand = rptTpl['布局框_集合'].find(item => item.Name === 'FooterBand');
  701. // 1. 高度
  702. if (footerBand) {
  703. let dftHeight = $("#footer_band_height_input")[0].value || 1;
  704. if (dftHeight === '') dftHeight = 1; // 计量的表脚默认高度给1(签名缘故)
  705. footerBand.Height = dftHeight * footersInfo.levels;
  706. }
  707. // 2.
  708. footerBandInfo.text_s = footersInfo.texts;
  709. footerBandInfo.discrete_field_s = footersInfo.fields;
  710. }
  711. if (signatureInfo && signatureInfo.length === 3) {
  712. rptTpl['电子签名离散指标_集合'] = signatureInfo[0];
  713. rptTpl['动态日期离散参数_集合'] = signatureInfo[1];
  714. rptTpl['电子签名审核意见指标_集合'] = signatureInfo[2];
  715. }
  716. },
  717. };