compare.js 13 KB

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