pm_share.js 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  1. 'use strict';
  2. /**
  3. *
  4. *
  5. * @author Zhong
  6. * @date 2018/6/28
  7. * @version
  8. */
  9. const pmShare = (function () {
  10. const spreadDom = $('#shareSpread');
  11. let spreadObj = {workBook: null, sheet: null};
  12. let preSelection = null;
  13. //项目分享类型,由别人分享给自己的,和自己分享给别人的
  14. const shareType = {receive: 'receive', shareTo: 'shareTo'};
  15. //操作类型
  16. const oprType = {copy: 'copy', cancel: 'cancel'};
  17. let tree = null;
  18. const treeCol = 0;
  19. const treeSetting = {
  20. tree: {
  21. id: 'ID',
  22. pid: 'ParentID',
  23. nid: 'NextSiblingID',
  24. rootId: -1,
  25. autoUpdate: false
  26. }
  27. };
  28. const headers = [
  29. {name: '工程列表', dataCode: 'name', width: 300, rateWidth: 0.55, vAlign: 'center', hAlign: 'left'},
  30. {name: '由...分享', dataCode: 'from', width: 120, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
  31. /* {name: '拷贝工程', dataCode: 'copy', width: 100, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},
  32. {name: '清除', dataCode: 'cancel', width: 100, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},*/
  33. {name: '工程造价', dataCode: 'engineeringCost', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  34. {name: '分部分项合计', dataCode: 'subEngineering', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  35. {name: '措施项目合计', dataCode: 'measure', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  36. {name: '其他项目合计', dataCode: 'other', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  37. {name: '规费', dataCode: 'charge', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  38. {name: '税金', dataCode: 'tax', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  39. {name: '占造价比例(%)', dataCode: 'rate', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  40. {name: '建筑面积', dataCode: 'buildingArea', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  41. {name: '单方造价', dataCode: 'perCost', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
  42. {name: '工程专业', dataCode: 'feeStandardName', width: 100, vAlign: 'center', hAlign: 'left'},
  43. ];
  44. const spreadOpts = {
  45. workBook: {
  46. tabStripVisible: false,
  47. allowContextMenu: false,
  48. allowCopyPasteExcelStyle : false,
  49. allowExtendPasteRange: false,
  50. allowUserDragDrop : false,
  51. allowUserDragFill: false,
  52. scrollbarMaxAlign : true
  53. },
  54. sheet: {
  55. isProtected: true,
  56. protectionOptions: {allowResizeRows: true, allowResizeColumns: true},
  57. clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
  58. }
  59. };
  60. const spreadEvents = {
  61. SelectionChanging: function (sender, info) {
  62. initSelection(info.newSelections[0], info.oldSelections[0]);
  63. }
  64. };
  65. //设置选中行底色
  66. //@param
  67. function setSelStyle(sel, backColor,sheet) {
  68. sel.row = sel.row === -1 ? 0 : sel.row;
  69. renderSheetFunc(sheet, function () {
  70. let style = projTreeObj.getSelStyle(backColor);
  71. for(let i = 0; i < sel.rowCount; i++){
  72. let row = i + sel.row;
  73. sheet.setStyle(row, -1, style);
  74. }
  75. });
  76. }
  77. //初始化焦点
  78. //@param {Object}newSel {Object}oldSel @return {void}
  79. function initSelection(newSel, oldSel = null) {
  80. let node = tree.items[newSel.row];
  81. tree.selected = node;
  82. shareSeleted = node;
  83. //恢复底色
  84. if(oldSel){
  85. setSelStyle(oldSel, projTreeObj.setting.style.defalutBackColor, spreadObj.sheet);
  86. }
  87. //设置选中行底色
  88. if(newSel){
  89. setSelStyle(newSel, projTreeObj.setting.style.selectedColor, spreadObj.sheet);
  90. }
  91. preSelection = newSel;
  92. }
  93. //渲染时方法,停止渲染
  94. //@param {Object}sheet {Function}func @return {void}
  95. function renderSheetFunc(sheet, func){
  96. sheet.suspendEvent();
  97. sheet.suspendPaint();
  98. if(func){
  99. func();
  100. }
  101. sheet.resumeEvent();
  102. sheet.resumePaint();
  103. }
  104. //设置表选项
  105. //@param {Object}workBook {Object}opts @return {void}
  106. function setSpreadOptions (workBook, opts) {
  107. for(let opt in opts.workBook){
  108. workBook.options[opt] = opts.workBook[opt];
  109. }
  110. for(let opt in opts.sheet){
  111. workBook.getActiveSheet().options[opt] = opts.sheet[opt];
  112. }
  113. }
  114. //建表头
  115. //@param {Object}sheet {Array}headers @return {void}
  116. function buildHeader(sheet, headers) {
  117. let fuc = function () {
  118. sheet.setColumnCount(headers.length);
  119. sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
  120. //let spreadWidth = getWorkBookWidth();
  121. for(let i = 0, len = headers.length; i < len; i++){
  122. sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
  123. if(headers[i].formatter){
  124. sheet.setFormatter(-1, i, headers[i].formatter);
  125. }
  126. /* if(headers[i].dataCode === oprType.copy){
  127. //合并列
  128. sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
  129. sheet.setValue(0, i, '操作', GC.Spread.Sheets.SheetArea.colHeader);
  130. continue;
  131. }*/
  132. sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
  133. sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
  134. sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
  135. }
  136. };
  137. renderSheetFunc(sheet, fuc);
  138. }
  139. //表监听事件
  140. //@param {Object}workBook @return {void}
  141. function bindEvent(workBook, events) {
  142. if(Object.keys(events).length === 0){
  143. return;
  144. }
  145. const Events = GC.Spread.Sheets.Events;
  146. for(let event in events){
  147. workBook.bind(Events[event], events[event]);
  148. }
  149. }
  150. //建表
  151. //@return {void}
  152. function buildSheet(){
  153. spreadObj.workBook = new GC.Spread.Sheets.Workbook(spreadDom[0], {sheetCount: 1});
  154. sheetCommonObj.spreadDefaultStyle(spreadObj.workBook);
  155. spreadObj.sheet = spreadObj.workBook.getActiveSheet();
  156. setSpreadOptions(spreadObj.workBook, spreadOpts);
  157. bindEvent(spreadObj.workBook, spreadEvents);
  158. buildHeader(spreadObj.sheet, headers);
  159. //全表不可编辑
  160. spreadObj.sheet.getRange(-1, -1, -1, -1).locked(true);
  161. }
  162. //此项目是否可以拷贝
  163. //@param {String}userID {Object}project @return {Boolean}
  164. function isAllowCopy(userID, project){
  165. for(let shareData of project.shareInfo){
  166. if(shareData.userID === userID){
  167. return shareData.allowCopy;
  168. }
  169. }
  170. return false;
  171. }
  172. //获取树节点
  173. //@param {Object}tree @return {Object}
  174. function getTreeNodeCell(tree){
  175. let indent = 20;
  176. let levelIndent = -5;
  177. let halfBoxLength = 5;
  178. let halfExpandLength = 3;
  179. let imgWidth = 18;
  180. let imgHeight = 14;
  181. let TreeNodeCellType = function () {
  182. };
  183. TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
  184. TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  185. if (style.backColor) {
  186. ctx.save();
  187. ctx.fillStyle = style.backColor;
  188. ctx.fillRect(x, y, w, h);
  189. ctx.restore();
  190. } else {
  191. ctx.clearRect(x, y, w, h);
  192. }
  193. let drawLine = function (canvas, x1, y1, x2, y2, color) {
  194. ctx.save();
  195. ctx.translate(0.5, 0.5);
  196. ctx.beginPath();
  197. ctx.moveTo(x1, y1);
  198. ctx.lineTo(x2, y2);
  199. ctx.strokeStyle = color;
  200. ctx.stroke();
  201. ctx.restore();
  202. };
  203. let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
  204. let rect = {}, h1, h2, offset = 1;
  205. rect.top = centerY - halfBoxLength;
  206. rect.bottom = centerY + halfBoxLength;
  207. rect.left = centerX - halfBoxLength;
  208. rect.right = centerX + halfBoxLength;
  209. if (rect.left < x + w) {
  210. rect.right = Math.min(rect.right, x + w);
  211. ctx.save();
  212. ctx.translate(0.5, 0.5);
  213. ctx.strokeStyle = 'black';
  214. ctx.beginPath();
  215. ctx.moveTo(rect.left, rect.top);
  216. ctx.lineTo(rect.left, rect.bottom);
  217. ctx.lineTo(rect.right, rect.bottom);
  218. ctx.lineTo(rect.right, rect.top);
  219. ctx.lineTo(rect.left, rect.top);
  220. ctx.stroke();
  221. ctx.fillStyle = 'white';
  222. ctx.fill();
  223. ctx.restore();
  224. // Draw Horizontal Line
  225. h1 = centerX - halfExpandLength;
  226. h2 = Math.min(centerX + halfExpandLength, x + w);
  227. if (h2 > h1) {
  228. drawLine(ctx, h1, centerY, h2, centerY, 'black');
  229. }
  230. // Draw Vertical Line
  231. if (!expanded && (centerX < x + w)) {
  232. drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
  233. }
  234. }
  235. }
  236. let node = tree.items[options.row];
  237. let showTreeLine = true;
  238. if (!node) { return; }
  239. let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  240. let x1 = centerX + indent / 2;
  241. let centerY = Math.floor((y + (y + h)) / 2);
  242. let y1;
  243. // Draw Sibling Line
  244. if (showTreeLine) {
  245. // Draw Horizontal Line
  246. if (centerX < x + w) {
  247. drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
  248. let img;
  249. if(node.data.projType === projectType.folder){
  250. img = document.getElementById('folder_open_pic');
  251. imgWidth = 15;
  252. }
  253. else if(node.data.projType === projectType.project){
  254. img = document.getElementById('proj_pic');
  255. imgWidth = 18;
  256. }
  257. else if(node.data.projType === projectType.engineering){
  258. img = document.getElementById('eng_pic');
  259. imgWidth = 14;
  260. }
  261. else if(node.data.projType === projectType.tender){
  262. img = document.getElementById('tender_pic');
  263. imgWidth = 14;
  264. }
  265. ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
  266. }
  267. // Draw Vertical Line
  268. if (centerX < x + w) {
  269. y1 = node.isLast() ? centerY : y + h;
  270. if (node.isFirst() && !node.parent.parent) {
  271. drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
  272. } else {
  273. drawLine(ctx, centerX, y, centerX, y1, 'gray');
  274. }
  275. }
  276. }
  277. // Draw Expand Box
  278. if (node.children.length > 0) {
  279. drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
  280. }
  281. // Draw Parent Line
  282. if (showTreeLine) {
  283. var parent = node.parent, parentCenterX = centerX - indent - levelIndent;
  284. while (parent.parent) {
  285. if (!parent.isLast()) {
  286. if (parentCenterX < x + w) {
  287. drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
  288. }
  289. }
  290. parent = parent.parent;
  291. parentCenterX -= (indent + levelIndent);
  292. }
  293. };
  294. // Draw Text
  295. arguments[2] = x + (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3;
  296. arguments[4] = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
  297. GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
  298. };
  299. TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  300. let info = {x: x, y: y, row: context.row, col: context.col, cellStyle: cellStyle, cellRect: cellRect, sheetArea: context.sheetArea};
  301. let node = tree.items[info.row];
  302. let offset = -1;
  303. let centerX = info.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  304. let text = context.sheet.getText(info.row, info.col);
  305. let value = context.sheet.getValue(info.row, info.col);
  306. let acStyle = context.sheet.getActualStyle(info.row, info.col),
  307. zoom = context.sheet.zoom();
  308. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: context.sheet, row: info.row, col: info.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  309. if(info.x > centerX + halfBoxLength && info.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength){
  310. info.isReservedLocation = true;
  311. }
  312. return info;
  313. };
  314. TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
  315. let offset = -1;
  316. let node = tree.items[hitinfo.row];
  317. let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  318. let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
  319. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  320. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  321. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  322. zoom = hitinfo.sheet.zoom();
  323. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  324. //(图标+名字)区域
  325. function withingClickArea(){
  326. return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
  327. }
  328. //点击单位工程
  329. if(node.data.projType === projectType.tender && withingClickArea()){
  330. let newTab = window.open('about:blank');
  331. //打开项目的实际ID
  332. BeforeOpenProject(node.data.actualTreeInfo.ID, {'fullFolder': GetFullFolder(node.parent)}, function () {
  333. let mainUrl = `/main?project=${node.data.actualTreeInfo.ID}`;
  334. CommonAjax.get(mainUrl, [], function () {
  335. newTab.location.href = mainUrl;
  336. });
  337. });
  338. }
  339. if (!node || node.children.length === 0) { return; }
  340. if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
  341. node.setExpanded(!node.expanded);
  342. TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
  343. let iCount = node.posterityCount(), i, child;
  344. for (i = 0; i < iCount; i++) {
  345. child = tree.items[hitinfo.row + i + 1];
  346. hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
  347. }
  348. hitinfo.sheet.invalidateLayout();
  349. });
  350. hitinfo.sheet.repaint();
  351. }
  352. };
  353. TreeNodeCellType.prototype.processMouseMove = function (hitInfo) {
  354. let sheet = hitInfo.sheet;
  355. let div = sheet.getParent().getHost();
  356. let canvasId = div.id + "vp_vp";
  357. let canvas = $(`#${canvasId}`)[0];
  358. //改变鼠标图案
  359. if (sheet && hitInfo.isReservedLocation) {
  360. canvas.style.cursor='pointer';
  361. return true;
  362. }else{
  363. canvas.style.cursor='default';
  364. }
  365. return false;
  366. };
  367. TreeNodeCellType.prototype.processMouseEnter = function (hitinfo) {
  368. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  369. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  370. let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
  371. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  372. zoom = hitinfo.sheet.zoom();
  373. let node = tree.items[hitinfo.row];
  374. let nodeIndent = node ? (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3 : 0;
  375. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  376. let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
  377. if(textLength > cellWidth - nodeIndent){
  378. TREE_SHEET_HELPER.showTipsDiv(text,{pos: {}},hitinfo);
  379. }
  380. };
  381. TreeNodeCellType.prototype.processMouseLeave = function (hitinfo) {
  382. TREE_SHEET_HELPER.tipDiv = 'hide';
  383. if (TREE_SHEET_HELPER._toolTipElement) {
  384. $(TREE_SHEET_HELPER._toolTipElement).hide();
  385. TREE_SHEET_HELPER._toolTipElement = null;
  386. };
  387. TREE_SHEET_HELPER.tipDivCheck();//延时检查:当tips正在show的时候,就调用了hide方法,会导致tips一直存在,所以设置一个超时处理
  388. }
  389. return new TreeNodeCellType();
  390. }
  391. //互动单元格
  392. function getInteractionCell() {
  393. let InteractionCell = function () {
  394. };
  395. InteractionCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
  396. InteractionCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  397. return {
  398. x: x,
  399. y: y,
  400. row: context.row,
  401. col: context.col,
  402. cellStyle: cellStyle,
  403. cellRect: cellRect,
  404. sheetArea: context.sheetArea,
  405. isReservedLocation: true
  406. };
  407. };
  408. InteractionCell.prototype.processMouseDown = function (hitinfo) {
  409. let dataCode = headers[hitinfo.col]['dataCode'];
  410. let node = tree.items[hitinfo.row];
  411. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  412. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  413. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  414. zoom = hitinfo.sheet.zoom();
  415. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  416. if(hitinfo.x - hitinfo.cellRect.x > 0 && hitinfo.x - hitinfo.cellRect.x < textLength){
  417. //由..分享,弹出分享者信息
  418. if(dataCode === 'from'){
  419. if(node.data.shareType === shareType.receive){
  420. $('#userinfo').find('h4').text(node.data.userInfo.name);
  421. $('#userinfo').find('h6').text(node.data.userInfo.company);
  422. let mobileHtml = `<i class="fa fa-tablet"> ${node.data.userInfo.mobile ? node.data.userInfo.mobile : ''}</i>`;
  423. $('#userinfo').find('li:first-child').html(mobileHtml);
  424. let emailHtml = `<i class="fa fa-envelope-o"> ${node.data.userInfo.email ? node.data.userInfo.email : ''}</i>`;
  425. $('#userinfo').find('li:last-child').html(emailHtml);
  426. $('#userinfo').modal('show');
  427. }
  428. }
  429. //分享给
  430. else if(dataCode === 'to'){
  431. if(node.data.shareType === shareType.shareTo){
  432. setShareToModal(node);
  433. $('#shareTo').modal('show');
  434. }
  435. }
  436. //操作
  437. else if(dataCode === oprType.copy){
  438. /* if(node.data.copy === '添加分享'){
  439. $('#sharePhone').val('');
  440. $('#share-info').hide();
  441. $('#share').find('.card').hide();
  442. $('#share').modal('show');
  443. $('#allowCopy').prop('checked', false);
  444. $('#allowCopyHint').hide();
  445. }
  446. else*/
  447. if(node.data.copy === '拷贝工程'){
  448. $('#copyShare').modal('show');
  449. }
  450. }
  451. else if (dataCode === oprType.cancel) {
  452. if (node.data.cancel === '清除') {
  453. let $p = $('<p>').text(`点“确定”按钮,确认清除分享文件 “${node.data.name}”。`);
  454. $('#cancelShare').find('.modal-body').empty();
  455. $('#cancelShare').find('.modal-body').append($p);
  456. $('#cancelShare').modal('show');
  457. }
  458. }
  459. }
  460. };
  461. InteractionCell.prototype.processMouseMove = function (hitInfo) {
  462. let dataCode = headers[hitInfo.col]['dataCode'];
  463. let node = tree.items[hitInfo.row];
  464. let sheet = hitInfo.sheet;
  465. let div = sheet.getParent().getHost();
  466. let canvasId = div.id + "vp_vp";
  467. let canvas = $(`#${canvasId}`)[0];
  468. //改变鼠标图案
  469. let text = hitInfo.sheet.getText(hitInfo.row, hitInfo.col);
  470. let value = hitInfo.sheet.getValue(hitInfo.row, hitInfo.col);
  471. let acStyle = hitInfo.sheet.getActualStyle(hitInfo.row, hitInfo.col),
  472. zoom = hitInfo.sheet.zoom();
  473. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitInfo.sheet, row: hitInfo.row, col: hitInfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  474. if (sheet && hitInfo.x - hitInfo.cellRect.x > 0 && hitInfo.x - hitInfo.cellRect.x < textLength) {
  475. canvas.style.cursor='pointer';
  476. return true;
  477. }else{
  478. canvas.style.cursor='default';
  479. }
  480. return false;
  481. };
  482. return new InteractionCell();
  483. }
  484. //设置分享给界面数据
  485. //@param {Object}selected @return {void}
  486. function setShareToModal(selected){
  487. $('#shareToInfo').empty();
  488. if(!selected){
  489. return;
  490. }
  491. let userIDs = [];
  492. for(let user of selected.data.shareInfo){
  493. userIDs.push(user.userID);
  494. }
  495. CommonAjax.post('/user/getUsers', {userIDs: userIDs}, function (rstData) {
  496. for(let userInfo of rstData){
  497. for(let user of selected.data.shareInfo){
  498. if(user.userID === userInfo._id){
  499. user.name = userInfo.real_name;
  500. user.company = userInfo.company;
  501. user.mobile = userInfo.mobile;
  502. user.email = userInfo.email;
  503. }
  504. }
  505. }
  506. let infoArr = [];
  507. for(let user of selected.data.shareInfo){
  508. let infoHtml = `<tr>
  509. <td style="width: 106px;">${user.name}</td>
  510. <td style="width: 146px;">${user.company}</td>
  511. <td style="width: 146px;">${user.mobile}</td>
  512. <td style="width: 156px;">${user.email}</td>
  513. <td style="width: 70px;text-align: center"><input value="allowCopy" ${user.allowCopy ? 'checked' : ''} type="checkbox"></td>
  514. <td style="width: 70px;text-align: center"><input value="cancelShare" type="checkbox"></td>
  515. </tr>`;
  516. infoArr.push(infoHtml);
  517. }
  518. let infoHtml = infoArr.join('');
  519. $('#shareToInfo').html(infoHtml);
  520. });
  521. }
  522. //更新项目分享信息
  523. //@param {Object}selected
  524. function updateShareInfo(selected){
  525. if(!selected){
  526. return;
  527. }
  528. let usersTr = $('#shareToInfo').find('tr');
  529. let newShareInfo = [];
  530. for(let i = 0; i < usersTr.length; i++){
  531. let userTr = usersTr[i];
  532. let allowCopy = $(userTr).find('input:first').prop('checked');
  533. let cancelShare = $(userTr).find('input:last').prop('checked');
  534. selected.data.shareInfo[i].allowCopy = allowCopy;
  535. if(!cancelShare){
  536. newShareInfo.push(selected.data.shareInfo[i]);
  537. }
  538. }
  539. CommonAjax.post('/pm/api/updateProjects', {user_id: userID, updateData: [{updateType: 'update', updateData: {ID: selected.data.ID, shareInfo: newShareInfo}}]}, function () {
  540. selected.data.shareInfo = newShareInfo;
  541. if(newShareInfo.length === 0){
  542. renderSheetFunc(spreadObj.sheet, function () {
  543. let rIdx = selected.serialNo();
  544. tree.removeNode(selected);
  545. spreadObj.sheet.deleteRows(rIdx, 1);
  546. spreadObj.sheet.setRowCount(tree.items);
  547. initSelection({row: spreadObj.sheet.getActiveRowIndex(), rowCount: 1},null);
  548. });
  549. }
  550. });
  551. }
  552. const foreColor = '#007bff';
  553. const cancelForeColor = 'red';
  554. //显示树结构数据
  555. //@param {Array}nodes {Array}headers @return {void}
  556. function showTreeData(nodes, headers){
  557. let sheet = spreadObj.workBook.getActiveSheet();
  558. let fuc = function(){
  559. sheet.setRowCount(nodes.length);
  560. for(let i = 0; i < nodes.length; i++){
  561. let treeNodeCell = getTreeNodeCell(tree);
  562. sheet.getCell(i, treeCol).cellType(treeNodeCell);
  563. for(let j = 0; j < headers.length; j++){
  564. sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
  565. sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
  566. let dataCode = headers[j].dataCode;
  567. if(dataCode === oprType.copy){
  568. let style = new GC.Spread.Sheets.Style();
  569. style.foreColor = foreColor;
  570. sheet.setStyle(i, j, style);
  571. sheet.getCell(i, j).cellType(getInteractionCell());
  572. }
  573. else if (dataCode === oprType.cancel) {
  574. let style = new GC.Spread.Sheets.Style();
  575. style.foreColor = cancelForeColor;
  576. sheet.setStyle(i, j, style);
  577. sheet.getCell(i, j).cellType(getInteractionCell());
  578. }
  579. else if(dataCode === 'from'){
  580. if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.receive){
  581. let style = new GC.Spread.Sheets.Style();
  582. style.foreColor = foreColor;
  583. sheet.setStyle(i, j, style);
  584. sheet.getCell(i, j).cellType(getInteractionCell());
  585. }
  586. }
  587. else if(dataCode === 'to'){
  588. if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.shareTo){
  589. let style = new GC.Spread.Sheets.Style();
  590. style.foreColor = foreColor;
  591. sheet.setStyle(i, j, style);
  592. sheet.getCell(i, j).cellType(getInteractionCell());
  593. }
  594. }
  595. sheet.setValue(i, j, nodes[i].data[dataCode] !== null && typeof nodes[i].data[dataCode] !== 'undefined' ? nodes[i].data[dataCode] : '');
  596. }
  597. }
  598. };
  599. renderSheetFunc(sheet, fuc);
  600. }
  601. //同一棵树,可能存在相同数据显示多条的问题(传入的datas中不存在相同数据),将真实树结构数据存在actualTreeInfo中,外部树结构数据用uuid重置。
  602. //@param {Array}datas
  603. function setTreeInfo(datas) {
  604. let IDMapping = {};
  605. for (let data of datas) {
  606. IDMapping[data.ID] = uuid.v1();
  607. }
  608. for (let data of datas) {
  609. data.actualTreeInfo = {ID: data.ID, ParentID: data.ParentID, NextSiblingID: data.NextSiblingID};
  610. data.ID = IDMapping[data.ID];
  611. data.NextSiblingID = IDMapping[data.NextSiblingID] ? IDMapping[data.NextSiblingID] : -1;
  612. data.ParentID = IDMapping[data.ParentID] ? IDMapping[data.ParentID] : -1;
  613. }
  614. }
  615. //整理同层数据的NextSiblingID,ParentID
  616. //@param {Array}datas {Number || String}pid @return {void}
  617. function sortSameDepthData(datas, pid) {
  618. for (let i = 0; i < datas.length; i++) {
  619. let data = datas[i],
  620. nextData = datas[i + 1];
  621. data.NextSiblingID = nextData ? nextData.ID : -1;
  622. data.ParentID = pid;
  623. }
  624. }
  625. //给项目设置分享信息:由xx分享、分享给我、可进行的操作,含有userInfo信息的文件为他人直接分享的文件,他人分享父级文件,子文件不含有userInfo信息
  626. //@param {Array}datas @return {void}
  627. function setShareInfo(datas) {
  628. for (let data of datas) {
  629. if (data.userInfo) {
  630. data.from = `由 ${data.userInfo.name} 分享`;
  631. data.to = '分享给 我';
  632. data.cancel = '清除';
  633. //拷贝操作只允许到单位工程级
  634. let tendersCanCopy = isAllowCopy(userID, data);
  635. let tenders = data.projType === projectType.tender ? [data] : _.filter(data.children, {projType: projectType.tender});
  636. for (let tender of tenders) {
  637. tender.copy = tendersCanCopy ? '拷贝工程' : '';
  638. }
  639. }
  640. }
  641. }
  642. //给项目设置汇总信息
  643. //@param {Array}projs {Object}summaryInfo
  644. function setSummaryInfo(grouped, summaryInfo) {
  645. if (!summaryInfo) {
  646. return;
  647. }
  648. let allDatas = [];
  649. for (let data of grouped) {
  650. allDatas.push(data);
  651. if (data.children && data.children.length > 0) {
  652. allDatas = allDatas.concat(data.children);
  653. }
  654. }
  655. for(let proj of allDatas){
  656. let summaryProj = summaryInfo[proj.ID];
  657. if(summaryProj){
  658. proj.engineeringCost = summaryProj.engineeringCost;
  659. proj.subEngineering = summaryProj.subEngineering;
  660. proj.measure = summaryProj.measure;
  661. proj.safetyConstruction = summaryProj.safetyConstruction;
  662. proj.other = summaryProj.other;
  663. proj.charge = summaryProj.charge;
  664. proj.tax = summaryProj.tax;
  665. proj.rate = summaryProj.rate;
  666. proj.buildingArea = summaryProj.buildingArea;
  667. proj.perCost = summaryProj.perCost;
  668. }
  669. }
  670. }
  671. //获取可成树的数据
  672. //@param {Array}datas @return {Array}
  673. function getTreeDatas(groupedDatas, ungroupedDatas){
  674. //设置新的树结构数据
  675. for (let data of groupedDatas) {
  676. setTreeInfo([data].concat(data.children));
  677. }
  678. let engs = _.filter(ungroupedDatas, {projType: projectType.engineering}),
  679. tenders = _.filter(ungroupedDatas, {projType: projectType.tender});
  680. for (let data of engs) {
  681. setTreeInfo([data].concat(data.children));
  682. }
  683. setTreeInfo(tenders);
  684. let rst = [];
  685. //整理树结构
  686. sortSameDepthData(groupedDatas, -1);
  687. //新建未分类建设项目及单项工程
  688. let ungroupedProj = {ID: uuid.v1(), ParentID: -1, NextSiblingID: -1, name: '未分类建设项目', projType: projectType.project};
  689. let ungroupedEng = {ID: uuid.v1(), ParentID: ungroupedProj.ID, NextSiblingID: -1, name: '未分类单项工程', projType: projectType.engineering};
  690. if (groupedDatas.length > 0) {
  691. groupedDatas[groupedDatas.length - 1].NextSiblingID = ungroupedProj.ID;
  692. }
  693. //将未分类的数据归类
  694. sortSameDepthData(engs, ungroupedProj.ID);
  695. sortSameDepthData(tenders, ungroupedEng.ID);
  696. //未分类单项工程处于同层第一个节点
  697. ungroupedEng.NextSiblingID = engs[0] ? engs[0].ID : ungroupedEng.NextSiblingID;
  698. let allDatas = groupedDatas.concat(ungroupedDatas);
  699. //设置分享信息及操作信息
  700. setShareInfo(allDatas);
  701. for (let data of allDatas) {
  702. rst.push(data);
  703. if (data.children) {
  704. rst = rst.concat(data.children);
  705. }
  706. }
  707. rst.push(ungroupedProj);
  708. rst.push(ungroupedEng);
  709. return rst;
  710. }
  711. //按照时间排序
  712. //@param {Array}datas @return {void}
  713. function sortByDate(datas){
  714. datas.sort(function (a, b) {
  715. let shareInfoA = _.find(a.shareInfo, {userID}),
  716. shareInfoB = _.find(b.shareInfo, {userID});
  717. let aV = shareInfoA ? Date.parse(shareInfoA.shareDate) : 0,
  718. bV = shareInfoB ? Date.parse(shareInfoB.shareDate) : 0;
  719. //时间越晚越靠前
  720. if (aV > bV) {
  721. return -1;
  722. } else if (aV < bV) {
  723. return 1;
  724. }
  725. return 0;
  726. });
  727. }
  728. //建立树
  729. //@return void
  730. function initShareTree(){
  731. $.bootstrapLoading.start();
  732. //获取分享数据
  733. CommonAjax.post('/pm/api/receiveProjects', {user_id: userID}, function (rstData) {
  734. // 排序 --分享的文件按照时间先后顺序排序,分享文件下的子文件,按照原本树结构显示,不需要排序
  735. sortByDate(rstData.grouped);
  736. sortByDate(rstData.ungrouped);
  737. //设置汇总信息
  738. if (rstData.summaryInfo) {
  739. setSummaryInfo(rstData.grouped, rstData.summaryInfo.grouped);
  740. setSummaryInfo(rstData.ungrouped, rstData.summaryInfo.ungrouped);
  741. }
  742. let treeDatas = getTreeDatas(rstData.grouped, rstData.ungrouped);
  743. tree = pmTree.createNew(treeSetting, treeDatas);
  744. tree.selected = tree.items[0];
  745. showTreeData(tree.items, headers);
  746. //初始选择
  747. let initSel = spreadObj.sheet.getSelections()[0] ? spreadObj.sheet.getSelections()[0] : {row: 0, rowCount: 1};
  748. initSelection(initSel);
  749. autoFlashHeight();
  750. spreadObj.sheet.frozenColumnCount(4);
  751. spreadObj.workBook.refresh();
  752. $.bootstrapLoading.end();
  753. });
  754. }
  755. //初始化右键菜单
  756. function initContextMenu() {
  757. $.contextMenu({
  758. selector: '#shareSpread',
  759. build: function ($trigger, e) {
  760. let target = SheetDataHelper.safeRightClickSelection($trigger, e, spreadObj.workBook);
  761. initSelection({row: target.row, rowCount: 1}, preSelection ? preSelection : null, spreadObj.sheet);
  762. return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  763. },
  764. items: {
  765. "copy": {
  766. name: "拷贝工程",
  767. icon: 'fa-copy',
  768. disabled: function () {
  769. let selected = tree.selected;
  770. return !(selected && selected.data.copy && selected.data.copy === '拷贝工程');
  771. },
  772. callback: function (key, opt) {
  773. $('#copyShare').modal('show');
  774. }
  775. },
  776. "cancel": {
  777. name: "清除",
  778. icon: 'fa-remove',
  779. disabled: function () {
  780. let selected = tree.selected;
  781. return !(selected && selected.data.cancel && selected.data.cancel === '清除');
  782. },
  783. callback: function (key, opt) {
  784. let $p = $('<p>').text(`点“确定”按钮,确认清除分享文件 “${tree.selected.data.name}”。`);
  785. $('#cancelShare').find('.modal-body').empty();
  786. $('#cancelShare').find('.modal-body').append($p);
  787. $('#cancelShare').modal('show');
  788. }
  789. }
  790. }
  791. });
  792. }
  793. //初始化视图
  794. //@return void
  795. function initView(){
  796. if(tree){
  797. tree = null;
  798. }
  799. if(spreadObj.workBook){
  800. spreadObj.workBook.destroy();
  801. spreadObj.workBook = null;
  802. }
  803. initContextMenu();
  804. buildSheet();
  805. initShareTree();
  806. }
  807. //根据建设项目获取单项工程
  808. //@param {Number}projID @return {void}
  809. function setEng(projID){
  810. let engQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: projectType.engineering, userID: userID, ParentID: projID};
  811. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: engQuery, options: '-_id -property'}, function (rstData) {
  812. $('#copyShare_selectEng').empty();
  813. for(let eng of rstData){
  814. let opt = $('<option>').val(eng.ID).text(eng.name);
  815. $('#copyShare_selectEng').append(opt);
  816. }
  817. });
  818. }
  819. //从其他建设项目中复制中,建设项目的文件层次结构名称和顺序
  820. //@param {Array}treeData @return {Array}
  821. function getFileHierarchyInfo(treeData){
  822. let tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
  823. tree.loadDatas(treeData);
  824. let items = tree.items;
  825. let rst = [];
  826. function getFileHierarchyName(node){
  827. let nodeName = node.data.name;
  828. let name = [];
  829. while (node.parent){
  830. name.push(node.parent.data.name ? node.parent.data.name : '');
  831. node = node.parent;
  832. }
  833. name = name.reverse();
  834. name.push(nodeName);
  835. return name.join('\\');
  836. }
  837. for(let node of items){
  838. if(node.children.length === 0 ){//project
  839. rst.push({ID: node.data.ID, fileHierarchyName: getFileHierarchyName(node)})
  840. }
  841. }
  842. return rst;
  843. }
  844. //设置拷贝工程下拉选择
  845. //@return {void}
  846. function setCopyModal(){
  847. //获取建设项目
  848. let projQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: {$in: [projectType.project, projectType.folder]}, userID: userID};
  849. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: projQuery, options: '-_id -property'}, function (rstData) {
  850. let fileHierarchyData = getFileHierarchyInfo(rstData);
  851. $('#copyShare_selectProj').empty();
  852. for(let proj of fileHierarchyData){
  853. let opt = $('<option>').val(proj.ID).text(proj.fileHierarchyName);
  854. $('#copyShare_selectProj').append(opt);
  855. }
  856. //初始选择
  857. if(fileHierarchyData.length > 0){
  858. setEng(fileHierarchyData[0].ID);
  859. }
  860. });
  861. }
  862. //拷贝分享的工程
  863. //@param {Object}selected {Number}parentID @return {void}
  864. function copyShareProject(selected, projID, engID){
  865. if(!engID || !selected){
  866. return;
  867. }
  868. let copyMap = {copy: null, update: null};
  869. let newName = getCopyName(selected);
  870. //获取单项工程的单位工程
  871. let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
  872. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, function (rstData) {
  873. let updateTender = null;
  874. for(let tender of rstData){
  875. if(tender.name === newName){
  876. $('#copyShare_name').text('已存在此单位工程。');
  877. $('#copyShare_name').addClass('text-danger');
  878. return;
  879. }
  880. if(tender.NextSiblingID == -1){
  881. updateTender = tender;
  882. }
  883. }
  884. //更新前节点
  885. if(updateTender){
  886. copyMap.update = {query: {ID: updateTender.ID}};
  887. }
  888. //拷贝
  889. let copyData = {
  890. userID: userID,
  891. ID: selected.data.actualTreeInfo.ID,
  892. NextSiblingID: -1,
  893. ParentID: engID,
  894. name: newName,
  895. shareInfo: [],
  896. compilation: selected.data.compilation,
  897. createDateTime: selected.data.createDateTime,
  898. fileVer: selected.data.fileVer ? selected.data.fileVer : '',
  899. projType: selected.data.projType,
  900. property: {},
  901. recentDateTime: selected.data.recentDateTime,
  902. fullFolder: selected.data.fullFolder
  903. };
  904. copyData.property.rootProjectID = projID;
  905. copyMap.copy = {document: copyData};
  906. $('#copyShare').modal('hide');
  907. $.bootstrapLoading.start();
  908. CommonAjax.post('/pm/api/copyProjects', {projectMap: copyMap, user_id: userID}, function (rstData) {
  909. $.bootstrapLoading.end();
  910. }, function () {
  911. $.bootstrapLoading.end();
  912. });
  913. });
  914. }
  915. //获取拷贝后的名称
  916. //@param {Object}node @return {String}
  917. function getCopyName(node) {
  918. //当前单位工程可能没有分享的用户信息,可能他人分享的是父级文件,userInfo在父级文件中
  919. let orgName = node.data.name,
  920. userInfo = node.data.userInfo;
  921. while (node && !userInfo) {
  922. node = node.parent;
  923. userInfo = node.data.userInfo;
  924. }
  925. return `${orgName} (${userInfo.name}分享拷贝)`;
  926. }
  927. //事件监听器
  928. //@return void
  929. function eventListener(){
  930. //tab
  931. $('#tab_pm_share').on('shown.bs.tab', function () {
  932. //侧滑隐藏
  933. $('.slide-sidebar').removeClass('open');
  934. $('.slide-sidebar').css('width', '0');
  935. projTreeObj.tree = null;
  936. if(projTreeObj.workBook){
  937. projTreeObj.workBook.destroy();
  938. projTreeObj.workBook = null;
  939. }
  940. gcTreeObj.tree = null;
  941. if(gcTreeObj.workBook){
  942. gcTreeObj.workBook.destroy();
  943. gcTreeObj.workBook = null;
  944. }
  945. initView();
  946. });
  947. //关闭拷贝工程
  948. $('#copyShare').on('hidden.bs.modal', function () {
  949. $('#copyShareProj-info').hide();
  950. $('#copyShareEng-info').hide();
  951. });
  952. //打开拷贝工程
  953. $('#copyShare').on('shown.bs.modal', function () {
  954. setCopyModal();
  955. //更改显示名称
  956. let newName = getCopyName(shareSeleted);
  957. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  958. $('#copyShare_name').removeClass('text-danger');
  959. });
  960. //拷贝工程改变选择建设项目
  961. $('#copyShare_selectProj').change(function () {
  962. //更改显示名称
  963. let newName = getCopyName(shareSeleted);
  964. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  965. $('#copyShare_name').removeClass('text-danger');
  966. $('#copyShareProj-info').hide();
  967. $('#copyShareEng-info').hide();
  968. let curSelID = $(this).select().val();
  969. setEng(parseInt(curSelID));
  970. });
  971. //拷贝工程改变选择单项工程
  972. $('#copyShare_selectEng').change(function () {
  973. //更改显示名称
  974. let newName = getCopyName(shareSeleted);
  975. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  976. $('#copyShare_name').removeClass('text-danger');
  977. });
  978. //确认拷贝
  979. $('#copyShare_confirm').click(function () {
  980. let selProj = $('#copyShare_selectProj').select().val();
  981. if(!selProj){
  982. $('#copyShareProj-info').show();
  983. return;
  984. }
  985. let selEng = $('#copyShare_selectEng').select().val();
  986. if(!selEng){
  987. $('#copyShareEng-info').show();
  988. return;
  989. }
  990. copyShareProject(tree.selected, parseInt(selProj), parseInt(selEng));
  991. });
  992. //清除分享
  993. $('#cancelShareConfirm').click(function () {
  994. $.bootstrapLoading.start();
  995. CommonAjax.post('/pm/api/share', {user_id: userID, type: oprType.cancel, projectID: tree.selected.data.actualTreeInfo.ID, shareData:[{userID: userID}]}, function (rstData) {
  996. $.bootstrapLoading.end();
  997. tree.removeNode(tree.selected);
  998. showTreeData(tree.items, headers);
  999. }, function () {
  1000. $.bootstrapLoading.end();
  1001. });
  1002. });
  1003. }
  1004. return {spreadObj, headers, initView, eventListener}
  1005. })();
  1006. $(document).ready(function () {
  1007. pmShare.eventListener();
  1008. });