compare.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Mai
  6. * @date 2018/5/15
  7. * @version
  8. */
  9. $(document).ready(function () {
  10. const spreadNS = GC.Spread.Sheets;
  11. class CompareObj {
  12. constructor (obj) {
  13. this.spread = new spreadNS.Workbook(obj, {sheetCount: 1});
  14. this.spread.options.tabStripVisible = false;
  15. this.spread.options.scrollbarMaxAlign = true;
  16. this.spread.options.cutCopyIndicatorVisible = false;
  17. this.spread.options.allowCopyPasteExcelStyle = false;
  18. this.spread.options.allowUserDragDrop = false;
  19. this.sheet = this.spread.getActiveSheet();
  20. //this.sheet.options.rowHeaderVisible = false;
  21. //this.sheet.options.colHeaderVisible = false;
  22. this.borderLine = new spreadNS.LineBorder('black', spreadNS.LineStyle.thin);
  23. this.paperSize = new spreadNS.Print.PaperSize(spreadNS.Print.PaperKind.a4);
  24. this.initCompareHeader([]);
  25. }
  26. initCompareHeader (tenders) {
  27. this.tenders = tenders;
  28. const cols = {}, colsName = [];
  29. const indexColCount = this.tenders.length > 0 ? this.tenders.length + 1 : 0;
  30. SpreadJsObj.beginMassOperationSheet(this.sheet);
  31. const spans = this.sheet.getSpans();
  32. for (const span of spans) {
  33. this.sheet.removeSpan(span.row, span.col);
  34. }
  35. this.sheet.setColumnCount(6 + indexColCount);
  36. this.sheet.setRowCount(2);
  37. this.sheet.frozenRowCount(2);
  38. const hCenter = spreadNS.HorizontalAlign.center;
  39. const vCenter = spreadNS.VerticalAlign.center;
  40. colsName.push('code');
  41. cols.code = 0;
  42. this.sheet.getCell(0, cols.code).text('指标编号').hAlign(hCenter).vAlign(vCenter);
  43. this.sheet.addSpan(0, cols.code, 2, 1);
  44. this.sheet.setColumnWidth(cols.code, 80);
  45. colsName.push('name');
  46. cols.name = 1;
  47. this.sheet.getCell(0, cols.name).text('项目或费用名称').hAlign(hCenter).vAlign(vCenter);
  48. this.sheet.addSpan(0, cols.name, 2, 1);
  49. this.sheet.setColumnWidth(cols.name, 220);
  50. colsName.push('unit1');
  51. cols.unit1 = 2;
  52. colsName.push('unit2');
  53. cols.unit2 = 3;
  54. this.sheet.getCell(0, cols.unit1).text('指标单位').hAlign(hCenter).vAlign(vCenter);
  55. this.sheet.addSpan(0, cols.unit1, 2, 2);
  56. this.sheet.setColumnWidth(cols.unit1, 65);
  57. this.sheet.setColumnWidth(cols.unit2, 65);
  58. if (this.tenders.length > 0) {
  59. this.sheet.getCell(0, cols.unit2+1).text('经济指标').hAlign(hCenter).vAlign(vCenter);
  60. this.sheet.addSpan(0, cols.unit2+1, 1, this.tenders.length);
  61. for (let i = 0, iLen = this.tenders.length; i < iLen; i++) {
  62. colsName.push('lib_' + this.tenders[i].lib_id);
  63. cols['lib_' + this.tenders[i].lib_id] = 4+i;
  64. this.sheet.getCell(1, cols['lib_' + this.tenders[i].lib_id])
  65. .text(this.tenders[i].filename).hAlign(hCenter).vAlign(vCenter);
  66. this.sheet.setColumnWidth(cols['lib_' + this.tenders[i].lib_id], 100);
  67. }
  68. colsName.push('averageIndex');
  69. cols.averageIndex = 4+this.tenders.length;
  70. this.sheet.getCell(0, cols.averageIndex).text('平均指标').hAlign(hCenter).vAlign(vCenter);
  71. this.sheet.addSpan(0, cols.averageIndex, 2, 1);
  72. this.sheet.setColumnWidth(cols.averageIndex, 100);
  73. }
  74. colsName.push('rule');
  75. cols.rule = 4+indexColCount;
  76. this.sheet.getCell(0, cols.rule).text('计算规则').hAlign(hCenter).vAlign(vCenter);
  77. this.sheet.addSpan(0, cols.rule, 2, 1);
  78. this.sheet.setColumnWidth(cols.rule, 300);
  79. colsName.push('memo');
  80. cols.memo = 5+indexColCount;
  81. this.sheet.getCell(0, cols.memo).text('备注').hAlign(hCenter).vAlign(vCenter);
  82. this.sheet.addSpan(0, cols.memo, 2, 1);
  83. this.sheet.setColumnWidth(cols.memo, 100);
  84. this.colsName = colsName;
  85. this.cols = cols;
  86. //this.sheet.getRange(0, 0, this.sheet.getRowCount(), this.sheet.getColumnCount()).setBorder(this.borderLine, {all: true});
  87. SpreadJsObj.endMassOperationSheet(this.sheet);
  88. }
  89. sortData (data) {
  90. function findTenderData (data, tenderId) {
  91. for (const tender of data) {
  92. if (tender.lib_id === tenderId) {
  93. return tender.data;
  94. }
  95. }
  96. return null;
  97. }
  98. function findNode(data, src, tenderId) {
  99. for (const node of data) {
  100. const field = 'bills_id' + tenderId;
  101. if (node.code === src.code && node.name === src.name && node[field] === src[field]) {
  102. return node;
  103. }
  104. }
  105. return null;
  106. }
  107. function findIndex(data, src) {
  108. for (const index of data) {
  109. if (index.code === src.code && index.name === src.name) {
  110. return index;
  111. }
  112. }
  113. return null;
  114. }
  115. const result = [];
  116. for (const tender of this.tenders) {
  117. const searchData = findTenderData(data, tender.lib_id);
  118. for (const node of searchData) {
  119. let sortNode = findNode(result, node, tender.lib_id);
  120. if (!sortNode) {
  121. sortNode = {
  122. code: node.code,
  123. name: node.name,
  124. indexes: [],
  125. };
  126. result.push(sortNode);
  127. }
  128. sortNode['bills_id' + tender.lib_id] = node.bills_id;
  129. for (const index of node.children) {
  130. let sortIndex = findIndex(sortNode.indexes, index);
  131. if (!sortIndex) {
  132. sortIndex = {
  133. code: index.code,
  134. name: index.name,
  135. unit1: index.unit1,
  136. unit2: index.unit2,
  137. sumValue: 0,
  138. rule: index.rule,
  139. memo: index.memo,
  140. };
  141. sortNode.indexes.push(sortIndex)
  142. }
  143. sortIndex['lib_' + tender.lib_id] = index.value;
  144. sortIndex.sumValue += index.value;
  145. }
  146. }
  147. }
  148. return result;
  149. }
  150. loadData (data) {
  151. const self = this;
  152. const vCenter = spreadNS.VerticalAlign.center;
  153. const colCount = compareObj.tenders.length > 0 ? 6+compareObj.tenders.length+1 : 6;
  154. this.searchData = data;
  155. this.showData = this.sortData(this.searchData);
  156. function loadNode (node, row) {
  157. self.sheet.getCell(row, self.cols.code).text(node.code).wordWrap(true).vAlign(vCenter);
  158. self.sheet.getCell(row, self.cols.name).text(node.name).wordWrap(true).vAlign(vCenter);
  159. self.sheet.getRange(row, 0, 1, colCount).backColor('#dae5ee');
  160. self.sheet.autoFitRow(row);
  161. }
  162. function loadIndex(index, row) {
  163. for (const colName of self.colsName) {
  164. if (colName === 'averageIndex') {
  165. const aver = Number((index.sumValue / self.tenders.length).toFixed(2));
  166. self.sheet.getCell(row, self.cols[colName]).value(aver).wordWrap(true).vAlign(vCenter);
  167. } else if (index[colName]) {
  168. self.sheet.getCell(row, self.cols[colName]).value(index[colName]).wordWrap(true).vAlign(vCenter);
  169. }
  170. }
  171. self.sheet.autoFitRow(row);
  172. }
  173. let iRow = 2;
  174. data.sort(function (a, b) {
  175. if (a.code > b.code) {
  176. return 1;
  177. } else if (a.code < b.code) {
  178. return -1;
  179. } else {
  180. return 0;
  181. }
  182. });
  183. SpreadJsObj.massOperationSheet(this.sheet, function () {
  184. self.sheet.setRowCount(2);
  185. for (const sd of self.showData) {
  186. self.sheet.addRows(iRow, 1);
  187. loadNode(sd, iRow);
  188. iRow += 1;
  189. for (const index of sd.indexes) {
  190. self.sheet.addRows(iRow, 1);
  191. loadIndex(index, iRow);
  192. iRow += 1;
  193. }
  194. }
  195. //self.sheet.getRange(-1, -1, self.sheet.getRowCount(), self.sheet.getColumnCount()).setBorder(self.borderLine, {all: true});
  196. });
  197. }
  198. searchIndex (keyword) {
  199. const self = this;
  200. const data = {
  201. tenders: this.tenders,
  202. keyword: keyword,
  203. };
  204. postData('/compare/search', data, function (datas) {
  205. self.loadData(datas);
  206. });
  207. }
  208. searchClass (data) {
  209. const self = this;
  210. data.tenders = this.tenders;
  211. postData('/compare/searchClass', data, function (datas) {
  212. self.loadData(datas);
  213. })
  214. }
  215. }
  216. const compareObj = new CompareObj($('#compare-spread')[0]);
  217. $('#generate-ok').click(function () {
  218. const select = $('tr[class!=table-secondary][lib_id]');
  219. const tender= [];
  220. for (let i = 0, iLen = select.length; i < iLen; i++) {
  221. tender.push({
  222. lib_id: parseInt($(select[i]).attr('lib_id')),
  223. filename: $('td:first', $(select[i])).text(),
  224. });
  225. }
  226. $('a[href="#generate-data"]').text('造价文件: ' + tender.length);
  227. compareObj.initCompareHeader(tender);
  228. $('#generate-data').modal('hide');
  229. });
  230. $('#search').click(function () {
  231. compareObj.searchIndex($('#keyword').val());
  232. $('.btn-secondary').removeClass('btn-secondary').addClass('btn-primary');
  233. });
  234. $('#index-zh').click(function () {
  235. $('.btn-secondary').removeClass('btn-secondary').addClass('btn-primary');
  236. $(this).removeClass('btn-primary').addClass('btn-secondary');
  237. $('#index-dy').text('单元指标');
  238. compareObj.searchClass(JSON.parse($(this).attr('data')));
  239. });
  240. $('#index-fx').click(function () {
  241. $('.btn-secondary').removeClass('btn-secondary').addClass('btn-primary');
  242. $(this).removeClass('btn-primary').addClass('btn-secondary');
  243. $('#index-dy').text('单元指标');
  244. compareObj.searchClass(JSON.parse($(this).attr('data')));
  245. });
  246. $('a[data]').click(function () {
  247. $('.btn-secondary').removeClass('btn-secondary').addClass('btn-primary');
  248. $('#index-dy').removeClass('btn-primary').addClass('btn-secondary').text($(this).text());
  249. compareObj.searchClass(JSON.parse($(this).attr('data')));
  250. });
  251. $('#export-excel').click(function () {
  252. const excelIo = new GC.Spread.Excel.IO();
  253. const date = new Date();
  254. const fileName = '指标对比.' + date.Format("yyyy.MM.dd.hh.mm.ss") + '.xlsx';
  255. const sJson = JSON.stringify(compareObj.spread.toJSON());
  256. excelIo.save(sJson, function(blob) {
  257. saveAs(blob, fileName);
  258. });
  259. });
  260. // $.contextMenu({
  261. // selector: '#compare-spread',
  262. // build: function ($trigger, e) {
  263. // const target = SpreadJsObj.safeRightClickSelection($trigger, e, compareObj.spread);
  264. // return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
  265. // },
  266. // items: {
  267. // 'print': {
  268. // name: '打印',
  269. // icon: 'fa-sign-in',
  270. // callback: function (key, opt) {
  271. // const printInfo = new spreadNS.Print.PrintInfo();
  272. // printInfo.showBorder(false);
  273. // printInfo.showGridLine(false);
  274. // printInfo.paperSize(compareObj.paperSize);
  275. // printInfo.orientation(spreadNS.Print.PrintPageOrientation.landscape);
  276. // printInfo.margin({top:20, bottom:20, left:20, right:20, header:10, footer:20});
  277. // //printInfo.qualityFactor(6);
  278. // compareObj.sheet.printInfo(printInfo);
  279. // compareObj.spread.print();
  280. // }
  281. // },
  282. // 'exportExcel': {
  283. // name: '导出excel',
  284. // callback: function (key, opt) {
  285. // const excelIo = new GC.Spread.Excel.IO();
  286. // const fileName = '1.xlsx';
  287. // const sJson = JSON.stringify(compareObj.spread.toJSON());
  288. // excelIo.save(sJson, function(blob) {
  289. // saveAs(blob, fileName);
  290. // });
  291. // }
  292. // },
  293. // 'exportPDF': {
  294. // name: '导出PDF',
  295. // callback: function (key, opt) {
  296. // compareObj.spread.savePDF();
  297. // }
  298. // }
  299. // }
  300. // });
  301. });