pm_gc.js 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278
  1. /**
  2. * Created by Zhong on 2017/10/30.
  3. */
  4. let gcTree = null;
  5. let decDate = null;//恢复后的名称后缀(时间+恢复)
  6. //恢复路径t = tender, e = engineering, p = project
  7. const recPath = {t: 'T', t_e: 'T_E', t_e_p: 'T_E_P', e: 'E', e_p: 'E_P', p: 'P'};
  8. const gcTreeObj = {
  9. tree: null,
  10. workBook: null,
  11. setting: {
  12. tree: {
  13. id: 'ID',
  14. pid: 'ParentID',
  15. nid: 'NextSiblingID',
  16. rootId: -1,
  17. autoUpdate: false
  18. },
  19. header: [
  20. {name: '工程列表', dataCode: 'name', width: 0.5, vAlign: 'center', hAlign: 'left'},
  21. {name: '删除日期', dataCode: 'deleteDateTime', width: 0.1, vAlign: 'center', hAlign: 'left'},
  22. {name: '创建日期', dataCode: 'createDateTime', width: 0.1, vAlign: 'center', hAlign: 'left'},
  23. {name: '恢复', dataCode: 'recovery', width: 0.05, vAlign: 'center', hAlign: 'left'},
  24. {name: '彻底删除', dataCode: 'delete', width: 0.05, vAlign: 'center', hAlign: 'left'},
  25. {name: '单价文件', dataCode: 'unitPriceFile', width: 0.05, vAlign: 'center', hAlign: 'left'},
  26. {name: '单价文件-清除', dataCode: 'unitPriceFile_delete', width: 0.05, vAlign: 'center', hAlign: 'left'},
  27. {name: '费率文件', dataCode: 'feeRateFile', width: 0.05, vAlign: 'center', hAlign: 'left'},
  28. {name: '费率文件-清除', dataCode: 'feeRateFile_delete', width: 0.05, vAlign: 'center', hAlign: 'left'}
  29. ],
  30. //恢复和彻底删除字体色
  31. style: {
  32. recForeColor: '#007bff',
  33. delForeColor: '#dc3545'
  34. },
  35. options: {
  36. tabStripVisible: false,
  37. allowContextMenu: false,
  38. allowCopyPasteExcelStyle : false,
  39. allowExtendPasteRange: false,
  40. allowUserDragDrop : false,
  41. allowUserDragFill: false,
  42. scrollbarMaxAlign : true
  43. }
  44. },
  45. renderSheetFuc: function (sheet, fuc) {
  46. sheet.suspendPaint();
  47. sheet.suspendEvent();
  48. fuc();
  49. sheet.resumePaint();
  50. sheet.resumeEvent();
  51. },
  52. setOptions: function (workbook, opts) {
  53. for(let opt in opts){
  54. workbook.options[opt] = opts[opt];
  55. }
  56. },
  57. bindEvent: function (workBook) {
  58. const _events = GC.Spread.Sheets.Events;
  59. let sheet = workBook.getActiveSheet();
  60. //改变选中节点set selected
  61. sheet.bind(_events.SelectionChanging, this.onSelectionChanging);
  62. },
  63. buildHeader: function (sheet, headers) {
  64. let me = this;
  65. let fuc = function () {
  66. sheet.options.isProtected = true;
  67. sheet.options.protectionOptions = {
  68. allowResizeRows: true,
  69. allowResizeColumns: true
  70. };
  71. let workBookWidth = getWorkBookWidth();
  72. sheet.setColumnCount(headers.length);
  73. sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
  74. for(let i = 0, len = headers.length; i < len; i++){
  75. sheet.setColumnWidth(i, workBookWidth * headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
  76. if(headers[i].dataCode === 'unitPriceFile' || headers[i].dataCode === 'feeRateFile'){
  77. //合并列
  78. sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
  79. }
  80. if(headers[i].dataCode === 'unitPriceFile_delete' || headers[i].dataCode === 'feeRateFile_delete'){
  81. continue;
  82. }
  83. sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
  84. }
  85. };
  86. me.renderSheetFuc(sheet, fuc);
  87. },
  88. buildSheet: function () {
  89. if(!this.workBook){
  90. this.workBook = new GC.Spread.Sheets.Workbook($('#gcSpread')[0], {sheetCount: 1});
  91. this.setOptions(this.workBook, this.setting.options);
  92. this.buildHeader(this.workBook.getActiveSheet(), this.setting.header);
  93. this.bindEvent(this.workBook);
  94. }
  95. },
  96. getSelStyle: function (backColor) {
  97. let style = new GC.Spread.Sheets.Style();
  98. style.backColor = backColor;
  99. style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
  100. style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
  101. style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
  102. style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin);
  103. return style;
  104. },
  105. //设置选中行底色
  106. setSelStyle: function (sel, backColor) {
  107. let me = this;
  108. let sheet = me.workBook.getSheet(0);
  109. me.renderSheetFuc(sheet, function () {
  110. let style = me.getSelStyle(backColor);
  111. /*sel.row = sel.row === -1 ? 0 : sel.row;*/
  112. for(let i = 0; i < sel.rowCount; i++){
  113. let row = i + sel.row;
  114. sheet.setStyle(row, -1, style);
  115. }
  116. });
  117. },
  118. initSelection: function (newSel, oldSel = null) {
  119. let me = this;
  120. let node = me.tree.items[newSel.row];
  121. me.tree.selected = node;
  122. //恢复底色
  123. if(oldSel){
  124. me.setSelStyle(oldSel, projTreeObj.setting.style.defalutBackColor);
  125. }
  126. //设置选中行底色
  127. if(newSel){
  128. me.setSelStyle(newSel, projTreeObj.setting.style.selectedColor);
  129. }
  130. },
  131. onSelectionChanging: function (sender, args) {
  132. let me = gcTreeObj;
  133. me.initSelection(args.newSelections[0], args.oldSelections[0]);
  134. },
  135. //点击恢复列,弹出恢复项目窗口
  136. oprProj: function (modalId, node) {
  137. let tenderNodes = m_getTenders(node);
  138. let type = modalId === '#rePoj' ? 'recovery' : 'delete';
  139. $(`${modalId} .modal-header`).empty();
  140. $('p', `${modalId} .modal-body`).remove();
  141. $(`${modalId} .modal-header`).html(v_getTitle(type, node));
  142. $(`${modalId} .modal-body`).html(v_getMoBody(type, node, tenderNodes));
  143. $(`${modalId}`).modal('show');
  144. },
  145. //点击单价文件恢复,弹出恢复单价文件窗口
  146. recoveryUnitPrc: function (node) {
  147. let unitPriceFiles = node.data.unitPriceFiles;
  148. let tenders = m_getTenders(node);
  149. $('#reFile h5').text('恢复单价文件');
  150. $('tr', '#reFile tbody').remove();
  151. $('#reFile tbody').html(v_getFiles(fileType.unitPriceFile, unitPriceFiles, tenders, 'recovery'));
  152. $('#reFile').modal('show');
  153. },
  154. recoveryFeeRate: function (node) {
  155. let feeRateFiles = node.data.feeRateFiles;
  156. let tenders = m_getTenders(node);
  157. $('#reFile h5').text('恢复费率文件');
  158. $('tr', '#reFile tbody').remove();
  159. $('#reFile tbody').html(v_getFiles(fileType.feeRateFile, feeRateFiles, tenders, 'recovery'));
  160. $('#reFile').modal('show');
  161. },
  162. //点击单价文件清除,弹出清除单价文件窗口
  163. deleteUnitPrc: function (node) {
  164. let unitPriceFiles = node.data.unitPriceFiles;
  165. let tenders = m_getTenders(node);
  166. $('#delFile h5').text('彻底删除单价文件');
  167. $('tr', '#delFile tbody').remove();
  168. $('#delFile tbody').html(v_getFiles(fileType.unitPriceFile, unitPriceFiles, tenders, 'delete'));
  169. $('#delFile').modal('show');
  170. },
  171. deleteFeeRate: function (node) {
  172. let feeRateFiles = node.data.feeRateFiles;
  173. let tenders = m_getTenders(node);
  174. $('#delFile h5').text('彻底删除费率文件');
  175. $('tr', '#delFile tbody').remove();
  176. $('#delFile tbody').html(v_getFiles(fileType.feeRateFile, feeRateFiles, tenders, 'delete'));
  177. $('#delFile').modal('show');
  178. },
  179. getTreeNodeCell: function (tree) {
  180. let indent = 20;
  181. let levelIndent = -5;
  182. let halfBoxLength = 5;
  183. let halfExpandLength = 3;
  184. let imgWidth = 18;
  185. let imgHeight = 14;
  186. let TreeNodeCellType = function () {
  187. };
  188. TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
  189. TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  190. if (style.backColor) {
  191. ctx.save();
  192. ctx.fillStyle = style.backColor;
  193. ctx.fillRect(x, y, w, h);
  194. ctx.restore();
  195. } else {
  196. ctx.clearRect(x, y, w, h);
  197. }
  198. let drawLine = function (canvas, x1, y1, x2, y2, color) {
  199. ctx.save();
  200. ctx.translate(0.5, 0.5);
  201. ctx.beginPath();
  202. ctx.moveTo(x1, y1);
  203. ctx.lineTo(x2, y2);
  204. ctx.strokeStyle = color;
  205. ctx.stroke();
  206. ctx.restore();
  207. };
  208. let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
  209. let rect = {}, h1, h2, offset = 1;
  210. rect.top = centerY - halfBoxLength;
  211. rect.bottom = centerY + halfBoxLength;
  212. rect.left = centerX - halfBoxLength;
  213. rect.right = centerX + halfBoxLength;
  214. if (rect.left < x + w) {
  215. rect.right = Math.min(rect.right, x + w);
  216. ctx.save();
  217. ctx.translate(0.5, 0.5);
  218. ctx.strokeStyle = 'black';
  219. ctx.beginPath();
  220. ctx.moveTo(rect.left, rect.top);
  221. ctx.lineTo(rect.left, rect.bottom);
  222. ctx.lineTo(rect.right, rect.bottom);
  223. ctx.lineTo(rect.right, rect.top);
  224. ctx.lineTo(rect.left, rect.top);
  225. ctx.stroke();
  226. ctx.fillStyle = 'white';
  227. ctx.fill();
  228. ctx.restore();
  229. // Draw Horizontal Line
  230. h1 = centerX - halfExpandLength;
  231. h2 = Math.min(centerX + halfExpandLength, x + w);
  232. if (h2 > h1) {
  233. drawLine(ctx, h1, centerY, h2, centerY, 'black');
  234. }
  235. // Draw Vertical Line
  236. if (!expanded && (centerX < x + w)) {
  237. drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
  238. }
  239. }
  240. }
  241. let node = tree.items[options.row];
  242. let showTreeLine = true;
  243. if (!node) { return; }
  244. let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  245. let x1 = centerX + indent / 2;
  246. let centerY = Math.floor((y + (y + h)) / 2);
  247. let y1;
  248. // Draw Sibling Line
  249. if (showTreeLine) {
  250. // Draw Horizontal Line
  251. if (centerX < x + w) {
  252. drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
  253. let img;
  254. if(node.data.projType === projectType.folder){
  255. img = document.getElementById('folder_open_pic');
  256. imgWidth = 15;
  257. }
  258. else if(node.data.projType === projectType.project){
  259. img = document.getElementById('proj_pic');
  260. imgWidth = 18;
  261. }
  262. else if(node.data.projType === projectType.engineering){
  263. img = document.getElementById('eng_pic');
  264. imgWidth = 14;
  265. }
  266. else if(node.data.projType === projectType.tender){
  267. img = document.getElementById('tender_pic');
  268. imgWidth = 14;
  269. }
  270. ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
  271. }
  272. // Draw Vertical Line
  273. if (centerX < x + w) {
  274. y1 = node.isLast() ? centerY : y + h;
  275. if (node.isFirst() && !node.parent.parent) {
  276. drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
  277. } else {
  278. drawLine(ctx, centerX, y, centerX, y1, 'gray');
  279. }
  280. }
  281. }
  282. // Draw Expand Box
  283. if (node.children.length > 0) {
  284. drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
  285. }
  286. // Draw Parent Line
  287. if (showTreeLine) {
  288. var parent = node.parent, parentCenterX = centerX - indent - levelIndent;
  289. while (parent.parent) {
  290. if (!parent.isLast()) {
  291. if (parentCenterX < x + w) {
  292. drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
  293. }
  294. }
  295. parent = parent.parent;
  296. parentCenterX -= (indent + levelIndent);
  297. }
  298. };
  299. // Draw Text
  300. //x = x + (node.depth() + 1) * indent + node.depth() * levelIndent;
  301. x = x + (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3;
  302. w = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
  303. GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
  304. };
  305. TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  306. let info = {x: x, y: y, row: context.row, col: context.col, cellStyle: cellStyle, cellRect: cellRect, sheetArea: context.sheetArea};
  307. let node = tree.items[info.row];
  308. let offset = -1;
  309. let centerX = info.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  310. let text = context.sheet.getText(info.row, info.col);
  311. let value = context.sheet.getValue(info.row, info.col);
  312. let acStyle = context.sheet.getActualStyle(info.row, info.col),
  313. zoom = context.sheet.zoom();
  314. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: context.sheet, row: info.row, col: info.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  315. if(info.x > centerX + halfBoxLength && info.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength){
  316. info.isReservedLocation = true;
  317. }
  318. return info;
  319. };
  320. TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
  321. let offset = -1;
  322. let node = tree.items[hitinfo.row];
  323. tree.selected = node;
  324. let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  325. let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;;
  326. if (!node || node.children.length === 0) { return; }
  327. if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
  328. node.setExpanded(!node.expanded);
  329. TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
  330. let iCount = node.posterityCount(), i, child;
  331. for (i = 0; i < iCount; i++) {
  332. child = tree.items[hitinfo.row + i + 1];
  333. hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
  334. }
  335. hitinfo.sheet.invalidateLayout();
  336. });
  337. hitinfo.sheet.repaint();
  338. }
  339. };
  340. TreeNodeCellType.prototype.processMouseEnter = function (hitinfo) {
  341. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  342. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  343. let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
  344. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  345. zoom = hitinfo.sheet.zoom();
  346. let node = tree.items[hitinfo.row];
  347. let nodeIndent = node ? (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3 : 0;
  348. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  349. let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
  350. if(textLength > cellWidth - nodeIndent){
  351. TREE_SHEET_HELPER.showTipsDiv(text,{pos: {}},hitinfo);
  352. }
  353. };
  354. TreeNodeCellType.prototype.processMouseLeave = function (hitinfo) {
  355. TREE_SHEET_HELPER.tipDiv = 'hide';
  356. if (TREE_SHEET_HELPER._toolTipElement) {
  357. $(TREE_SHEET_HELPER._toolTipElement).hide();
  358. TREE_SHEET_HELPER._toolTipElement = null;
  359. };
  360. TREE_SHEET_HELPER.tipDivCheck();//延时检查:当tips正在show的时候,就调用了hide方法,会导致tips一直存在,所以设置一个超时处理
  361. }
  362. return new TreeNodeCellType();
  363. },
  364. getBaseCell: function () {
  365. let MyBaseCell = function () {
  366. };
  367. MyBaseCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
  368. MyBaseCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  369. return {
  370. x: x,
  371. y: y,
  372. row: context.row,
  373. col: context.col,
  374. cellStyle: cellStyle,
  375. cellRect: cellRect,
  376. sheetArea: context.sheetArea,
  377. isReservedLocation: true
  378. };
  379. };
  380. MyBaseCell.prototype.processMouseDown = function (hitinfo) {
  381. let dataCode = gcTreeObj.setting.header[hitinfo.col]['dataCode'];
  382. let node = gcTreeObj.tree.items[hitinfo.row];
  383. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  384. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  385. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  386. zoom = hitinfo.sheet.zoom();
  387. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  388. if(hitinfo.x - hitinfo.cellRect.x > 0 && hitinfo.x - hitinfo.cellRect.x < textLength){
  389. //恢复
  390. if(dataCode === 'recovery'){
  391. gcTreeObj.oprProj('#rePoj', node);
  392. }
  393. //清除
  394. else if(dataCode === 'delete'){
  395. gcTreeObj.oprProj('#delPoj', node)
  396. }
  397. //恢复单价文件
  398. else if(dataCode === 'unitPriceFile'){
  399. gcTreeObj.recoveryUnitPrc(node);
  400. }
  401. //清除单价文件
  402. else if(dataCode === 'unitPriceFile_delete'){
  403. gcTreeObj.deleteUnitPrc(node);
  404. }
  405. //恢复费率文件
  406. else if(dataCode === 'feeRateFile'){
  407. gcTreeObj.recoveryFeeRate(node);
  408. }
  409. //清除费率文件
  410. else if(dataCode === 'feeRateFile_delete'){
  411. gcTreeObj.deleteFeeRate(node);
  412. }
  413. }
  414. };
  415. MyBaseCell.prototype.processMouseMove = function (hitInfo) {
  416. let dataCode = gcTreeObj.setting.header[hitInfo.col]['dataCode'];
  417. if(dataCode === 'recovery' || dataCode === 'delete' || dataCode === 'unitPriceFile' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile' || dataCode === 'feeRateFile_delete'){
  418. let sheet = hitInfo.sheet;
  419. let div = sheet.getParent().getHost();
  420. let canvasId = div.id + "vp_vp";
  421. let canvas = $(`#${canvasId}`)[0];
  422. //改变鼠标图案
  423. let text = hitInfo.sheet.getText(hitInfo.row, hitInfo.col);
  424. let value = hitInfo.sheet.getValue(hitInfo.row, hitInfo.col);
  425. let acStyle = hitInfo.sheet.getActualStyle(hitInfo.row, hitInfo.col),
  426. zoom = hitInfo.sheet.zoom();
  427. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitInfo.sheet, row: hitInfo.row, col: hitInfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  428. if (sheet && hitInfo.x - hitInfo.cellRect.x > 0 && hitInfo.x - hitInfo.cellRect.x < textLength) {
  429. canvas.style.cursor='pointer';
  430. return true;
  431. }else{
  432. canvas.style.cursor='default';
  433. }
  434. }
  435. return false;
  436. };
  437. return new MyBaseCell();
  438. },
  439. setCellValue: function (cell, node) {
  440. const sheet = this.workBook.getActiveSheet();
  441. const {row, col} = cell;
  442. const dataCode = this.setting.header[col]['dataCode'];
  443. let value = '';
  444. if(dataCode === 'deleteDateTime' || dataCode === 'createDateTime'){
  445. if (node.data.projType === projectType.tender && deleted(node)) {
  446. let date = dataCode === 'deleteDateTime' ? node.data.deleteInfo.deleteDateTime : node.data.createDateTime;
  447. let localDateTime = new Date(date).toLocaleDateString();
  448. value = new Date(localDateTime).Format('yyyy-MM-dd');
  449. }
  450. }
  451. else if(dataCode === 'recovery'){
  452. if(deleted(node)){
  453. value = '恢复';
  454. }
  455. }
  456. else if(dataCode === 'delete'){
  457. if(deleted(node)){
  458. value = '彻底删除';
  459. }
  460. }
  461. else if(dataCode === 'unitPriceFile'){
  462. if(node.data.projType === projectType.project && node.data.unitPriceFiles !== undefined && node.data.unitPriceFiles.length > 0){
  463. value = '恢复';
  464. }
  465. }
  466. else if(dataCode === 'unitPriceFile_delete'){
  467. if(node.data.projType === projectType.project && node.data.unitPriceFiles !== undefined && node.data.unitPriceFiles.length > 0){
  468. value = '彻底删除';
  469. }
  470. }
  471. else if(dataCode === 'feeRateFile'){
  472. if(node.data.projType === projectType.project && node.data.feeRateFiles !== undefined && node.data.feeRateFiles.length > 0){
  473. value = '恢复';
  474. }
  475. }
  476. else if(dataCode === 'feeRateFile_delete'){
  477. if(node.data.projType === projectType.project && node.data.feeRateFiles !== undefined && node.data.feeRateFiles.length > 0){
  478. value = '彻底删除';
  479. }
  480. }
  481. else {
  482. value = node.data[dataCode] ? node.data[dataCode] : '';
  483. }
  484. sheet.setValue(row, col, value);
  485. },
  486. showTreeData: function (nodes, headers) {
  487. let me = this;
  488. let sheet = me.workBook.getActiveSheet();
  489. let fuc = function(){
  490. sheet.setRowCount(nodes.length);
  491. for(let i = 0; i < nodes.length; i++){
  492. let treeNodeCell = me.getTreeNodeCell(me.tree);
  493. sheet.getCell(i, 0).cellType(treeNodeCell);
  494. for(let j = 0; j < headers.length; j++){
  495. sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
  496. sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
  497. if(j !== 0){
  498. sheet.getCell(i, j).cellType(me.getBaseCell());
  499. }
  500. let dataCode = headers[j].dataCode;
  501. if(dataCode === 'recovery' || dataCode === 'unitPriceFile' || dataCode === 'feeRateFile'){
  502. let style = new GC.Spread.Sheets.Style();
  503. style.foreColor = me.setting.style.recForeColor;
  504. sheet.setStyle(-1, j, style);
  505. }
  506. else if(dataCode === 'delete' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile_delete'){
  507. let style = new GC.Spread.Sheets.Style();
  508. style.foreColor = me.setting.style.delForeColor;
  509. sheet.setStyle(-1, j, style);
  510. }
  511. me.setCellValue({row: i, col: j}, nodes[i]);
  512. }
  513. }
  514. };
  515. me.renderSheetFuc(sheet, fuc);
  516. },
  517. refreshNodeData: function (node) {
  518. let me = this;
  519. let sheet = me.workBook.getActiveSheet();
  520. let header = me.setting.header;
  521. let rIdx = me.tree.items.indexOf(node);
  522. me.renderSheetFuc(sheet, function () {
  523. for(let i = 0; i < header.length; i++){
  524. me.setCellValue({row: rIdx, col: i}, node);
  525. }
  526. });
  527. },
  528. remove: function (node) {
  529. let me = this;
  530. let sheet = me.workBook.getActiveSheet();
  531. //删除行号
  532. let rIdx = me.tree.items.indexOf(node);
  533. //删除行数
  534. let count = node.posterityCount() + 1;
  535. me.tree.removeNode(node);
  536. me.renderSheetFuc(sheet, function () {
  537. sheet.deleteRows(rIdx, count);
  538. sheet.setRowCount(me.tree.items.length);
  539. me.initSelection({row: sheet.getActiveRowIndex(), rowCount: 1});
  540. });
  541. },
  542. move: function (orgRow, newRow) {
  543. this.workBook.getActiveSheet().deleteRows(orgRow, 1);
  544. this.addRow(this.tree.items[newRow]);
  545. }
  546. };
  547. $(document).ready(function () {
  548. $('#tab_pm_gc').on('show.bs.tab', function () {
  549. //侧滑隐藏
  550. $('.slide-sidebar').removeClass('open');
  551. $('.slide-sidebar').css('width', '0');
  552. gc_init();
  553. if(projTreeObj.workBook){
  554. projTreeObj.workBook.destroy();
  555. projTreeObj.workBook = null;
  556. }
  557. projTreeObj.tree = null;
  558. });
  559. e_recFiles($('#reFileBtn'));
  560. e_delFiles($('#delFileBtn'));
  561. e_recProj($('#rePojBtn'));
  562. e_delProj($('#delPojBtn'));
  563. });
  564. function gc_init(){
  565. $.bootstrapLoading.start();
  566. a_getGC(function (datas) {
  567. m_buildVirtualTree(datas);
  568. let normalDatas = m_VTreeToDatas(datas);
  569. gcTreeObj.tree = pmTree.createNew(gcTreeObj.setting, normalDatas);
  570. gcTreeObj.tree.selected = gcTreeObj.tree.items[0];
  571. gcTreeObj.buildSheet();
  572. gcTreeObj.showTreeData(gcTreeObj.tree.items, gcTreeObj.setting.header);
  573. //初始选择
  574. let initSel = gcTreeObj.workBook.getSheet(0).getSelections()[0] ? gcTreeObj.workBook.getSheet(0).getSelections()[0] : {row: 0, rowCount: 1};
  575. gcTreeObj.initSelection(initSel);
  576. autoFlashHeight();
  577. gcTreeObj.workBook.refresh();
  578. $.bootstrapLoading.end();
  579. });
  580. }
  581. //项目恢复模态框标题
  582. function v_getTitle(type, node){
  583. let html = '';
  584. html += type === 'recovery' ? '<h5 class="modal-title">恢复 ' : '<h5 class="modal-title">彻底删除 ';
  585. if(node.data.projType === projectType.project){
  586. html += '<i class="fa fa-cubes"></i>建设项目</h5>';
  587. }
  588. else if(node.data.projType === projectType.engineering){
  589. html += '<i class="fa fa-cube"></i>单项工程</h5>';
  590. }
  591. else if(node.data.projType === projectType.tender){
  592. html += '<i class="fa fa-sticky-note-o"></i>单位工程</h5>';
  593. }
  594. html += '<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
  595. return html;
  596. }
  597. //项目恢复模态框主体
  598. function v_getMoBody(type, oprNode, nodes){
  599. let html = '';
  600. if(type === 'recovery'){
  601. if(oprNode.data.projType === projectType.tender){
  602. decDate = '(' + new Date().Format('MM-dd hh:mm:ss') + '恢复)';
  603. let recName = oprNode.data.name + decDate;
  604. html += '<p>恢复后将重命名为 <b>' + recName + '</b></p>';
  605. }
  606. else {
  607. if(oprNode.data.projType === projectType.project){
  608. html += '<p><i class="fa fa-cubes"></i> ' + oprNode.data.name + '下的单位工程都将恢复都将恢复,恢复后将重命名为</p>';
  609. }
  610. else if(oprNode.data.projType === projectType.engineering){
  611. html += '<p><i class="fa fa-cube"></i> ' + oprNode.data.name + '下的单位工程都将恢复都将恢复,恢复后将重命名为</p>';
  612. }
  613. html += ('<p>');
  614. for(let i = 0, len = nodes.length; i < len; i++){
  615. let recName = nodes[i].data.name + '(' + new Date().Format('MM-dd hh:mm:ss') +'恢复)';
  616. html += '<b>' + recName + '</b>、';
  617. }
  618. html = html.slice(0, html.length - 1);
  619. html += ('</p>');
  620. }
  621. html += ('<p>点“确定”按钮,确认从回收站中恢复。</p>');
  622. }
  623. else{
  624. html += ('<p>点“确定”按钮,确认彻底删除数据。</p>');
  625. }
  626. return html;
  627. }
  628. //单价、费率文件恢复弹出框数据
  629. function v_getFiles(type, files, tenders, opr = null){
  630. let html = '';
  631. function hasTheFile(tenders, fileId, fileType){
  632. for(let tender of tenders){
  633. let fileAttr = fileType === 'UnitPriceFile' ? 'unitPriceFile' : 'feeFile';
  634. if(tender.data.property[fileAttr]['id'] == fileId){
  635. return true;
  636. }
  637. }
  638. return false;
  639. }
  640. for(let i = 0, len = files.length; i < len; i ++){
  641. let recName = type === fileType.unitPriceFile ? files[i].name + '单价文件' : files[i].name + '费率文件';
  642. let fileId = type === fileType.unitPriceFile ? files[i].id : files[i].ID;
  643. let recTimeA = formatDate(new Date(files[i].deleteInfo.deleteDateTime), 'yyyy-MM-dd');
  644. let recTimeB = formatDate(new Date(files[i].deleteInfo.deleteDateTime), 'HH:mm:ss');
  645. if(opr && opr === 'delete'){
  646. //还被引用,不可删除
  647. if(hasTheFile(tenders, fileId, type)){
  648. html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input disabled name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
  649. }
  650. else {
  651. html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
  652. }
  653. }
  654. else{
  655. html += '<tr><td width="266px">'+ recName +'</td><td width="136px">' + recTimeA + '<br>' + recTimeB + '</td><td width="64px"><input name="fileItems" type="checkbox" fileId = "' + fileId + '" fileType = "' + type + '"></td></tr>';
  656. }
  657. }
  658. return html;
  659. }
  660. //恢复或清除单价、费率文件后前端显示变化
  661. function v_refreshFiles(project, fileIds, type){
  662. let projFiles;
  663. if(type === fileType.unitPriceFile){
  664. projFiles = project.data.unitPriceFiles;
  665. }
  666. else if(type === fileType.feeRateFile){
  667. projFiles = project.data.feeRateFiles;
  668. }
  669. if(projFiles && projFiles.length > 0){
  670. let tempFiles = [];
  671. for(let i = 0, len = projFiles.length; i < len; i++){
  672. let isExist = false;
  673. for(let j = 0, jLen = fileIds.length; j < jLen; j++){
  674. let id = projFiles[i].id || projFiles[i].ID || null;
  675. if(id && id === fileIds[j]){
  676. isExist = true;
  677. break;
  678. }
  679. }
  680. if(!isExist){
  681. tempFiles.push(projFiles[i]);
  682. }
  683. }
  684. if(type === fileType.unitPriceFile){
  685. project.data.unitPriceFiles = tempFiles;
  686. }
  687. else if(type === fileType.feeRateFile){
  688. project.data.feeRateFiles = tempFiles;
  689. }
  690. }
  691. }
  692. function v_removeNode(node){
  693. gcTreeObj.remove(node);
  694. let parent = node.parent || null;
  695. if(parent && parent.children.length === 0 && parent.data !== undefined){
  696. if(parent.data.projType === projectType.project && fileEmpty(parent)){
  697. v_removeNode(parent);
  698. }
  699. else if(parent.data.projType !== projectType.project){
  700. v_removeNode(parent);
  701. }
  702. }
  703. }
  704. function v_refreshNode(node, recovery = true){
  705. if(recovery){
  706. if(deleted(node)){
  707. delete node.data.deleteInfo;
  708. }
  709. }
  710. gcTreeObj.refreshNodeData(node);
  711. let parent = node.parent || null;
  712. if(parent && parent.data !== undefined){
  713. v_refreshNode(parent, recovery);
  714. }
  715. }
  716. //将获取的回收站中的数据建虚拟树
  717. function m_buildVirtualTree(datas){
  718. for(let i = 0, len = datas.length; i < len; i++){
  719. if(datas[i].projType === projectType.project){
  720. datas[i].ParentID = -1;
  721. }
  722. let children = datas[i].children || null;
  723. if(children){
  724. m_buildVirtualTree(children);
  725. }
  726. let next = datas[i+1] || null;
  727. if(next){
  728. datas[i].NextSiblingID = next.ID;
  729. }
  730. else {
  731. datas[i].NextSiblingID = -1;
  732. }
  733. }
  734. }
  735. function m_VTreeToDatas(datas){
  736. let rst = [];
  737. let projs = datas;
  738. rst = rst.concat(projs);
  739. for(let i = 0, len = projs.length; i < len; i++){
  740. let p_engs = projs[i].children || null;
  741. if(p_engs){
  742. rst = rst.concat(p_engs);
  743. for(let j = 0, jLen = p_engs.length; j < jLen; j ++){
  744. let e_tenders = p_engs[j].children || null;
  745. if(e_tenders){
  746. rst = rst.concat(e_tenders);
  747. }
  748. }
  749. }
  750. }
  751. return rst;
  752. }
  753. //获得当前节点的tenders数据,模态提示框用
  754. function m_getTenders(node){
  755. if(node.data.projType === projectType.tender) return [node];
  756. else {
  757. let rst = [];
  758. if(node.children.length > 0){
  759. node.children.forEach(function (cNode) {
  760. if(cNode.children.length > 0){
  761. cNode.children.forEach(function (ccNode) {
  762. if(ccNode.data.projType === projectType.tender) rst.push(ccNode);
  763. });
  764. }
  765. else if(cNode.children.length === 0 && cNode.data.projType === projectType.tender){
  766. rst.push(cNode);
  767. }
  768. });
  769. }
  770. return rst;
  771. }
  772. }
  773. //获得要更新的数据(包含恢复的数据,维护项目管理树的数据)
  774. function m_getRecDatas(oprNode){
  775. let rst = Object.create(null);
  776. let rstProj = [], rstFile = [];
  777. let path;
  778. if(oprNode.data.projType === projectType.tender){
  779. path = recPath.t;
  780. let engineering = oprNode.parent || null;
  781. if(!engineering) return null;
  782. let project = engineering.parent || null;
  783. if(!project) return null;
  784. if(engineering && deleted(engineering)){
  785. path = recPath.t_e;
  786. }
  787. //恢复建设项目
  788. if(project && deleted(project)){
  789. path = recPath.t_e_p;
  790. }
  791. //恢复单价、费率文件
  792. rstFile = rstFile.concat(getUpdateFiles([oprNode], project));
  793. if(path === recPath.t){
  794. rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, true));
  795. }
  796. else if(path === recPath.t_e){
  797. rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, false));
  798. rstProj = rstProj.concat(getUpdateDatas(projectType.engineering, engineering, -1, true));
  799. }
  800. else if(path === recPath.t_e_p){
  801. rstProj = rstProj.concat(getUpdateDatas(projectType.tender, oprNode, -1, false));
  802. rstProj = rstProj.concat(getUpdateDatas(projectType.engineering, engineering, -1, false));
  803. rstProj = rstProj.concat(getUpdateDatas(projectType.project, project, -1, false));
  804. }
  805. }
  806. else if(oprNode.data.projType === projectType.engineering){
  807. path = recPath.e;
  808. let project = oprNode.parent || null;
  809. if(!project) return null;
  810. //恢复建设项目
  811. if(project && deleted(project)){
  812. path = recPath.e_p;
  813. }
  814. let tenders = oprNode.children;
  815. if(tenders.length > 0){
  816. for(let i = 0, len = tenders.length; i < len; i++){
  817. rstProj = rstProj.concat(getUpdateDatas(projectType.tender, tenders[i], tenders[i].data.NextSiblingID, false));
  818. }
  819. rstProj = deWeightName(rstProj);
  820. //恢复单价、费率文件
  821. rstFile = rstFile.concat(getUpdateFiles(tenders, project));
  822. }
  823. if(path === recPath.e){
  824. rstProj= rstProj.concat(getUpdateDatas(projectType.engineering, oprNode, -1, true));
  825. }
  826. else if(path === recPath.e_p){
  827. rstProj= rstProj.concat(getUpdateDatas(projectType.engineering, oprNode, -1, false));
  828. rstProj= rstProj.concat(getUpdateDatas(projectType.project, project, -1, false));
  829. }
  830. }
  831. else if(oprNode.data.projType === projectType.project){
  832. path = recPath.p;
  833. let engineerings = oprNode.children;
  834. if(engineerings.length > 0){
  835. let allTenders = [], rstEngs = [];
  836. for(let i = 0, len = engineerings.length; i < len; i++){
  837. //恢复单项工程
  838. rstEngs = rstEngs.concat(getUpdateDatas(projectType.engineering, engineerings[i], engineerings[i].data.NextSiblingID, false));
  839. let tenders = engineerings[i].children;
  840. allTenders = allTenders.concat(tenders);
  841. let rstTends = [];
  842. for(let j = 0, jLen = tenders.length; j < jLen; j++){
  843. //恢复单位工程
  844. rstTends = rstTends.concat(getUpdateDatas(projectType.tender, tenders[j], tenders[j].data.NextSiblingID, false));
  845. }
  846. //去除重名
  847. rstTends = deWeightName(rstTends);
  848. rstProj = rstProj.concat(rstTends);
  849. }
  850. //去除重名
  851. rstEngs = deWeightName(rstEngs);
  852. rstProj = rstProj.concat(rstEngs);
  853. //恢复单价、费率文件
  854. rstFile = rstFile.concat(getUpdateFiles(allTenders, oprNode));
  855. }
  856. //恢复建设项目
  857. rstProj = rstProj.concat(getUpdateDatas(projectType.project, oprNode, false, false));
  858. }
  859. rst.proj = rstProj;
  860. rst.file = rstFile;
  861. return rst;
  862. }
  863. //获取清除的数据
  864. function m_getDelDatas(oprNode){
  865. let rst = [];
  866. if(!oprNode){
  867. return rst;
  868. }
  869. function getChild(node){
  870. rst.push({updateType: 'Project', ID: node.data.ID});
  871. if(node.children.length > 0){
  872. for(let child of node.children){
  873. getChild(child);
  874. }
  875. }
  876. }
  877. getChild(oprNode);
  878. //父节点只有一个单位工程,则清除此单位工程的时候,父节点也清除,(建设项目单价、费率文件存在时不清除)
  879. if(oprNode.data.projType === projectType.tender){
  880. let eng = oprNode.parent, proj = null;
  881. if(eng && deleted(eng)){
  882. proj = eng.parent;
  883. rst.push({updateType: 'Project', ID: eng.data.ID});
  884. }
  885. if(proj && deleted(proj) && fileEmpty(proj)){
  886. rst.push({updateType: 'Project', ID: proj.data.ID})
  887. }
  888. }
  889. else if(oprNode.data.projType === projectType.engineering){
  890. let proj = oprNode.parent;
  891. if(proj && deleted(proj) && fileEmpty(proj)){
  892. rst.push({updateType: 'Project', ID: proj.data.ID});
  893. }
  894. }
  895. else if(oprNode.data.projType === projectType.project){
  896. for(let uf of oprNode.data.unitPriceFiles){
  897. rst.push({updateType: fileType.unitPriceFile, ID: uf.id});
  898. }
  899. for(let ff of oprNode.data.feeRateFiles){
  900. rst.push({updateType: fileType.feeRateFile, ID: ff.ID});
  901. }
  902. }
  903. return rst;
  904. }
  905. //获得勾选的单价、费率文件的id
  906. function m_getFilesObjs(nodes){
  907. let rst = [];
  908. for(let i = 0, len = nodes.length; i < len; i++){
  909. let fileId = $(nodes[i]).attr('fileId') || null;
  910. if(fileId){
  911. let dispName = $('td:eq(0)', $(nodes[i])[0].parentNode.parentNode)[0].textContent;
  912. let name = dispName.slice(0, dispName.length - 4);
  913. if($(nodes[i]).attr('fileType') === fileType.unitPriceFile){
  914. fileId = parseInt(fileId);
  915. }
  916. let obj = Object.create(null);
  917. obj.id = fileId;
  918. obj.name = name;
  919. rst.push(obj);
  920. }
  921. }
  922. return rst;
  923. }
  924. function m_project(node){
  925. if(node && node.data.projType === projectType.project) return node;
  926. if(!node) return null;
  927. let parent = node.parent || null;
  928. if(!parent) return null;
  929. if(parent && parent.data.projType === projectType.project) return parent;
  930. let gParent = parent.parent || null;
  931. if(!gParent) return null;
  932. if(gParent && gParent.data.projType === projectType.project) return gParent;
  933. return null;
  934. }
  935. //点击单价文件、费率文件下的恢复操作(确认)
  936. function e_recFiles(btn){
  937. btn.bind('click', function () {
  938. decDate = '(' + new Date().Format('MM-dd hh:mm:ss') + '恢复)';
  939. let recObjs = m_getFilesObjs($('[name = "fileItems"]:checked'));
  940. let recIds = [];
  941. for(let i of recObjs){
  942. recIds.push(i.id);
  943. }
  944. let type = $('[name = "fileItems"]:checked').attr('fileType');
  945. let selected = gcTreeObj.tree.selected;
  946. //backend
  947. let updateDatas = [];
  948. for(let i = 0, len = recObjs.length; i < len; i++){
  949. let findData = type === fileType.unitPriceFile ? {id: recObjs[i].id} : {ID: recObjs[i].id};
  950. updateDatas.push(getUpdateObj(type, findData, {deleteInfo: null, name: delPostFix(recObjs[i].name) + decDate}));
  951. }
  952. //恢复建设项目
  953. if(updateDatas.length > 0 && deleted(selected)){
  954. updateDatas.push(getUpdateObj(projectType.project, {ID: selected.data.ID}, {deleteInfo: null, name: delPostFix(selected.data.name) + decDate}));
  955. }
  956. updateDatas = deWeightName(updateDatas);
  957. a_rec(updateDatas, caller);
  958. function caller(){
  959. //front
  960. if(recIds.length > 0){
  961. v_refreshFiles(selected, recIds, type);
  962. if(deleted(selected)){
  963. delete selected.data.deleteInfo;
  964. }
  965. if(fileEmpty(selected) && selected.children.length === 0){
  966. gcTreeObj.remove(selected);
  967. }
  968. else {
  969. gcTreeObj.refreshNodeData(selected);
  970. }
  971. }
  972. }
  973. });
  974. }
  975. //点击单价、费率文件的清除操作(确认)
  976. function e_delFiles(btn){
  977. btn.bind('click', function () {
  978. let selected = gcTreeObj.tree.selected;//project
  979. let delObjs = m_getFilesObjs($('[name = "fileItems"]:checked'));
  980. let type = $('[name = "fileItems"]:checked').attr('fileType');
  981. let delDatas = [];
  982. let delIds = [];
  983. for(let delObj of delObjs){
  984. delIds.push(delObj.id);
  985. delDatas.push({updateType: type, ID: delObj.id});
  986. }
  987. //此操作造成了建设项目的文件为空,则清除建设项目
  988. if(fileWillEmpty(selected, delIds, type)){
  989. //delDatas.push({updateType: 'Project', ID: selected.data.ID});
  990. }
  991. if(delDatas.length > 0){
  992. //backend
  993. a_delGC(delDatas, caller);
  994. //front
  995. function caller(){
  996. v_refreshFiles(selected, delIds, type);
  997. if(fileEmpty(selected) && selected.children.length === 0){
  998. gcTreeObj.remove(selected);
  999. }
  1000. else {
  1001. gcTreeObj.refreshNodeData(selected);
  1002. }
  1003. }
  1004. }
  1005. });
  1006. }
  1007. //点击项目下的恢复操作(确认)
  1008. function e_recProj(btn){
  1009. btn.bind('click', function () {
  1010. let selected = gcTreeObj.tree.selected;
  1011. //backend
  1012. let updateObj = m_getRecDatas(selected);
  1013. let updateDatas = updateObj.proj.concat(updateObj.file);
  1014. let fileObj = getRecFileObj(updateObj.file);
  1015. //保存成功后回调front
  1016. a_rec(updateDatas, caller);
  1017. function caller() {
  1018. let project = m_project(selected);
  1019. if(project){
  1020. if(fileObj[fileType.unitPriceFile].length > 0){
  1021. v_refreshFiles(project, fileObj[fileType.unitPriceFile], fileType.unitPriceFile);
  1022. }
  1023. if(fileObj[fileType.feeRateFile].length > 0){
  1024. v_refreshFiles(project, fileObj[fileType.feeRateFile], fileType.feeRateFile);
  1025. }
  1026. }
  1027. v_removeNode(selected);
  1028. v_refreshNode(selected, true);
  1029. }
  1030. });
  1031. }
  1032. function e_delProj(btn){
  1033. btn.bind('click', function () {
  1034. let selected = gcTreeObj.tree.selected;
  1035. //backend
  1036. let delDatas = m_getDelDatas(selected);
  1037. if(delDatas.length > 0){
  1038. a_delGC(delDatas, caller);
  1039. }
  1040. //front
  1041. function caller() {
  1042. v_removeNode(selected);
  1043. v_refreshNode(selected, false);
  1044. }
  1045. });
  1046. }
  1047. function a_getGC(callback){
  1048. CommonAjax.post('/pm/api/getGCDatas', {user_id: userID}, function (rstData) {
  1049. if(callback){
  1050. callback(rstData);
  1051. }
  1052. });
  1053. }
  1054. function a_rec(nodes, callback){
  1055. CommonAjax.post('/pm/api/recGC', {user_id: userID, nodes: nodes}, function (rstData) {
  1056. if(callback){
  1057. callback();
  1058. }
  1059. });
  1060. }
  1061. function a_delGC(delDatas, callback){
  1062. CommonAjax.post('/pm/api/delGC', {user_id: userID, delDatas: delDatas}, function(rstData){
  1063. if(callback){
  1064. callback();
  1065. }
  1066. })
  1067. }
  1068. //去除重名,回收站不处理重名,只保证恢复到项目管理中不出现重名
  1069. function deWeightName(datas){
  1070. let rst = [];
  1071. let _deWeight = Object.create(null), prefix = 'name_';
  1072. //按同名分组
  1073. for(let i = 0, len = datas.length; i < len; i++){
  1074. let data = datas[i];
  1075. let _names = _deWeight[prefix + data.updateData.name] || null;
  1076. if(!_names){
  1077. _names = _deWeight[prefix + data.updateData.name] = [];
  1078. }
  1079. if(_names){
  1080. _names.push(data);
  1081. }
  1082. }
  1083. for(let _name in _deWeight){
  1084. let sameNameDatas = _deWeight[_name];
  1085. let count = 0;
  1086. for(let i = 0, len = sameNameDatas.length; i < len; i++){
  1087. let postFix = '(' + count + ')';
  1088. if(i > 0){
  1089. sameNameDatas[i].updateData.name = sameNameDatas[i].updateData.name + postFix;
  1090. }
  1091. count ++;
  1092. rst.push(sameNameDatas[i]);
  1093. }
  1094. }
  1095. return rst;
  1096. }
  1097. //去除名称后缀(Date恢复)
  1098. function delPostFix (str){
  1099. let rst = '';
  1100. rst = delPostRecFix(delPostNameFix(str));
  1101. return rst;
  1102. }
  1103. function delPostRecFix (str){
  1104. let rst = '';
  1105. let re = /(+[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2}恢复)/g;
  1106. rst = str.replace(re, '');
  1107. return rst;
  1108. }
  1109. function delPostNameFix (str){
  1110. let rst = '';
  1111. let re = /(+[0-9][0-9]*)/g;
  1112. rst = str.replace(re, '');
  1113. return rst;
  1114. }
  1115. function deleted(node){
  1116. return node.data.deleteInfo !== undefined && node.data.deleteInfo && node.data.deleteInfo.deleted;
  1117. }
  1118. function fileEmpty(node){
  1119. return node.data.unitPriceFiles.length === 0 && node.data.feeRateFiles.length === 0;
  1120. }
  1121. function fIsExist(files, id, type){
  1122. let isExist = false;
  1123. for(let i = 0, len = files.length; i < len; i++){
  1124. if((type === fileType.unitPriceFile && files[i].id === parseInt(id)) || (type === fileType.feeRateFile && files[i].ID === id)){
  1125. isExist = true;
  1126. break;
  1127. }
  1128. }
  1129. return isExist;
  1130. }
  1131. //删除的文件是否会导致建设项目不再存有文件
  1132. function fileWillEmpty(proj, delIds, type){
  1133. let ufs = proj.data.unitPriceFiles,
  1134. ffs = proj.data.feeRateFiles;
  1135. let theFiles = type === fileType.unitPriceFile ? ufs : ffs;
  1136. otherFiles = type === fileType.unitPriceFile ? ffs : ufs;
  1137. let uniqIds = Array.from(new Set(delIds));
  1138. if(theFiles.length === delIds.length){
  1139. for(let id of uniqIds){
  1140. if(!fIsExist(theFiles, id, type)){
  1141. return false;
  1142. }
  1143. }
  1144. }
  1145. if(otherFiles.length === 0){
  1146. return true;
  1147. }
  1148. return false;
  1149. }
  1150. function getRecFileObj(files){
  1151. let rst = Object.create(null);
  1152. let rst_UF = [], rst_FF = [];
  1153. for(let i = 0, len = files.length; i < len; i++){
  1154. if(files[i].findData !== undefined){
  1155. if(files[i].updateType === fileType.unitPriceFile && files[i].findData.id !== undefined){
  1156. rst_UF.push(files[i].findData.id);
  1157. }
  1158. else if(files[i].updateType === fileType.feeRateFile && files[i].findData.ID !== undefined){
  1159. rst_FF.push(files[i].findData.ID);
  1160. }
  1161. }
  1162. }
  1163. rst[fileType.unitPriceFile] = rst_UF;
  1164. rst[fileType.feeRateFile] = rst_FF;
  1165. return rst;
  1166. }
  1167. function getUpdateObj(updateType, findData, updateData){
  1168. let obj = Object.create(null);
  1169. obj.updateType = updateType;
  1170. obj.findData = findData;
  1171. obj.updateData = updateData;
  1172. return obj;
  1173. }
  1174. function getUpdateDatas(updateType, node, mtNID, mtPM){
  1175. let rst = [];
  1176. decDate = '(' + new Date().Format('MM-dd hh:mm:ss') + '恢复)';
  1177. let newName = delPostFix(node.data.name) + decDate;
  1178. if(updateType === projectType.tender || updateType === projectType.engineering){
  1179. //维护项目管理树
  1180. if(mtPM){
  1181. rst.push(getUpdateObj(updateType, {ParentID: node.data.ParentID, NextSiblingID: -1, deleteInfo: null}, {NextSiblingID: node.data.ID}));
  1182. }
  1183. //恢复
  1184. if(mtNID){
  1185. rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {name: newName, deleteInfo: null, NextSiblingID: mtNID}));
  1186. }
  1187. else {
  1188. rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {name: newName, deleteInfo: null}));
  1189. }
  1190. }
  1191. else if(updateType === projectType.project){
  1192. //恢复
  1193. rst.push(getUpdateObj(updateType, {ID: node.data.ID}, {deleteInfo: null, name: newName}));//NextSibling为undefined,后端处理
  1194. }
  1195. return rst;
  1196. }
  1197. //unitPriceFile or feeRateFile
  1198. function getUpdateFiles(tenders, project){
  1199. let rstUF = [], rstFF = [], rst = [];
  1200. let _unitFiles = Object.create(null), _feeFiles = Object.create(null), prefix = '_id';
  1201. decDate = '(' + new Date().Format('MM-dd hh:mm:ss') + '恢复)';
  1202. for(let i = 0, len = tenders.length; i < len; i++){
  1203. //恢复单价文件
  1204. if(project && project.data.unitPriceFiles.length > 0 && fIsExist(project.data.unitPriceFiles, tenders[i].data.property.unitPriceFile.id, fileType.unitPriceFile)){
  1205. //unitFiles.push(tenders[i].data.property.unitPriceFile.id);
  1206. let propId = tenders[i].data.property.unitPriceFile.id;
  1207. let propName = tenders[i].data.property.unitPriceFile.name;
  1208. let _uf = _unitFiles[prefix + propId] || null;
  1209. if(!_uf){
  1210. let obj = Object.create(null);
  1211. obj.id = parseInt(propId);
  1212. obj.name = propName;
  1213. _unitFiles[prefix + propId] = obj;
  1214. }
  1215. }
  1216. //恢复费率文件
  1217. if(project && project.data.feeRateFiles.length > 0 && fIsExist(project.data.feeRateFiles, tenders[i].data.property.feeFile.id, fileType.feeRateFile)){
  1218. //feeFiles.push(tenders[i].data.property.feeFile.id);
  1219. let propId = tenders[i].data.property.feeFile.id;
  1220. let propName = tenders[i].data.property.feeFile.name;
  1221. let _ff = _feeFiles[prefix + propId] || null;
  1222. if(!_ff){
  1223. let obj = Object.create(null);
  1224. obj.id = propId;
  1225. obj.name = propName;
  1226. _feeFiles[prefix + propId] = obj;
  1227. }
  1228. }
  1229. }
  1230. for(let uf in _unitFiles){
  1231. rstUF.push(getUpdateObj(fileType.unitPriceFile, {id: _unitFiles[uf].id}, {deleteInfo: null, name: delPostFix(_unitFiles[uf].name) + decDate}));
  1232. }
  1233. for(let ff in _feeFiles){
  1234. rstFF.push(getUpdateObj(fileType.feeRateFile, {ID: _feeFiles[ff].id}, {deleteInfo: null, name: delPostFix(_feeFiles[ff].name) + decDate}));
  1235. }
  1236. rst = rst.concat(deWeightName(rstUF));
  1237. rst = rst.concat(deWeightName(rstFF));
  1238. return rst;
  1239. }