pm_share.js 47 KB

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