pm_share.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  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. //项目分享类型,由别人分享给自己的,和自己分享给别人的
  13. const shareType = {receive: 'receive', shareTo: 'shareTo'};
  14. let tree = null;
  15. const treeSetting = {
  16. tree: {
  17. id: 'ID',
  18. pid: 'ParentID',
  19. nid: 'NextSiblingID',
  20. rootId: -1,
  21. autoUpdate: false
  22. }
  23. };
  24. const headers = [
  25. {name: '工程列表', dataCode: 'name', width: 0.55, vAlign: 'center', hAlign: 'left'},
  26. {name: '由...分享', dataCode: 'from', width: 0.15, vAlign: 'center', hAlign: 'left'},
  27. {name: '分享给...', dataCode: 'to', width: 0.15, vAlign: 'center', hAlign: 'left'},
  28. {name: '操作', dataCode: 'operation', width: 0.15, vAlign: 'center', hAlign: 'left'},
  29. ];
  30. const spreadOpts = {
  31. workBook: {
  32. tabStripVisible: false,
  33. allowContextMenu: false,
  34. allowCopyPasteExcelStyle : false,
  35. allowExtendPasteRange: false,
  36. allowUserDragDrop : false,
  37. allowUserDragFill: false,
  38. scrollbarMaxAlign : true
  39. },
  40. sheet: {
  41. isProtected: true,
  42. protectionOptions: {allowResizeRows: true, allowResizeColumns: true},
  43. clipBoardOptions: GC.Spread.Sheets.ClipboardPasteOptions.values
  44. }
  45. };
  46. const spreadEvents = {
  47. SelectionChanging: function (sender, info) {
  48. initSelection(info.newSelections[0], info.oldSelections[0]);
  49. }
  50. };
  51. //设置选中行底色
  52. //@param
  53. function setSelStyle(sel, backColor,sheet) {
  54. sel.row = sel.row === -1 ? 0 : sel.row;
  55. renderSheetFunc(sheet, function () {
  56. let style = projTreeObj.getSelStyle(backColor);
  57. for(let i = 0; i < sel.rowCount; i++){
  58. let row = i + sel.row;
  59. sheet.setStyle(row, -1, style);
  60. }
  61. });
  62. }
  63. //初始化焦点
  64. //@param {Object}newSel {Object}oldSel @return {void}
  65. function initSelection(newSel, oldSel = null) {
  66. let node = tree.items[newSel.row];
  67. tree.selected = node;
  68. shareSeleted = node;
  69. //恢复底色
  70. if(oldSel){
  71. setSelStyle(oldSel, projTreeObj.setting.style.defalutBackColor, spreadObj.sheet);
  72. }
  73. //设置选中行底色
  74. if(newSel){
  75. setSelStyle(newSel, projTreeObj.setting.style.selectedColor, spreadObj.sheet);
  76. }
  77. }
  78. //渲染时方法,停止渲染
  79. //@param {Object}sheet {Function}func @return {void}
  80. function renderSheetFunc(sheet, func){
  81. sheet.suspendEvent();
  82. sheet.suspendPaint();
  83. if(func){
  84. func();
  85. }
  86. sheet.resumeEvent();
  87. sheet.resumePaint();
  88. }
  89. //设置表选项
  90. //@param {Object}workBook {Object}opts @return {void}
  91. function setSpreadOptions (workBook, opts) {
  92. for(let opt in opts.workBook){
  93. workBook.options[opt] = opts.workBook[opt];
  94. }
  95. for(let opt in opts.sheet){
  96. workBook.getActiveSheet().options[opt] = opts.sheet[opt];
  97. }
  98. }
  99. //建表头
  100. //@param {Object}sheet {Array}headers @return {void}
  101. function buildHeader(sheet, headers) {
  102. let fuc = function () {
  103. sheet.setColumnCount(headers.length);
  104. sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
  105. let spreadWidth = getWorkBookWidth();
  106. for(let i = 0, len = headers.length; i < len; i++){
  107. sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
  108. sheet.setColumnWidth(i, spreadWidth * headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
  109. if(headers[i].formatter){
  110. sheet.setFormatter(-1, i, headers[i].formatter);
  111. }
  112. sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
  113. sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
  114. }
  115. };
  116. renderSheetFunc(sheet, fuc);
  117. }
  118. //表监听事件
  119. //@param {Object}workBook @return {void}
  120. function bindEvent(workBook, events) {
  121. if(Object.keys(events).length === 0){
  122. return;
  123. }
  124. const Events = GC.Spread.Sheets.Events;
  125. for(let event in events){
  126. workBook.bind(Events[event], events[event]);
  127. }
  128. }
  129. //建表
  130. //
  131. function buildSheet(){
  132. spreadObj.workBook = new GC.Spread.Sheets.Workbook(spreadDom[0], {sheetCount: 1});
  133. sheetCommonObj.spreadDefaultStyle(spreadObj.workBook);
  134. spreadObj.sheet = spreadObj.workBook.getActiveSheet();
  135. setSpreadOptions(spreadObj.workBook, spreadOpts);
  136. bindEvent(spreadObj.workBook, spreadEvents);
  137. buildHeader(spreadObj.sheet, headers);
  138. //全表不可编辑
  139. spreadObj.sheet.getRange(-1, -1, -1, -1).locked(true);
  140. }
  141. //此项目是否可以拷贝
  142. //@param {String}userID {Object}project @return {Boolean}
  143. function isAllowCopy(userID, project){
  144. for(let shareData of project.shareInfo){
  145. if(shareData.userID === userID){
  146. return shareData.allowCopy;
  147. }
  148. }
  149. return false;
  150. }
  151. //
  152. //
  153. function getTreeNodeCell(tree){
  154. let indent = 20;
  155. let levelIndent = -5;
  156. let halfBoxLength = 5;
  157. let halfExpandLength = 3;
  158. let imgWidth = 18;
  159. let imgHeight = 14;
  160. let TreeNodeCellType = function () {
  161. };
  162. TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
  163. TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  164. if (style.backColor) {
  165. ctx.save();
  166. ctx.fillStyle = style.backColor;
  167. ctx.fillRect(x, y, w, h);
  168. ctx.restore();
  169. } else {
  170. ctx.clearRect(x, y, w, h);
  171. }
  172. let drawLine = function (canvas, x1, y1, x2, y2, color) {
  173. ctx.save();
  174. ctx.translate(0.5, 0.5);
  175. ctx.beginPath();
  176. ctx.moveTo(x1, y1);
  177. ctx.lineTo(x2, y2);
  178. ctx.strokeStyle = color;
  179. ctx.stroke();
  180. ctx.restore();
  181. };
  182. let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
  183. let rect = {}, h1, h2, offset = 1;
  184. rect.top = centerY - halfBoxLength;
  185. rect.bottom = centerY + halfBoxLength;
  186. rect.left = centerX - halfBoxLength;
  187. rect.right = centerX + halfBoxLength;
  188. if (rect.left < x + w) {
  189. rect.right = Math.min(rect.right, x + w);
  190. ctx.save();
  191. ctx.translate(0.5, 0.5);
  192. ctx.strokeStyle = 'black';
  193. ctx.beginPath();
  194. ctx.moveTo(rect.left, rect.top);
  195. ctx.lineTo(rect.left, rect.bottom);
  196. ctx.lineTo(rect.right, rect.bottom);
  197. ctx.lineTo(rect.right, rect.top);
  198. ctx.lineTo(rect.left, rect.top);
  199. ctx.stroke();
  200. ctx.fillStyle = 'white';
  201. ctx.fill();
  202. ctx.restore();
  203. // Draw Horizontal Line
  204. h1 = centerX - halfExpandLength;
  205. h2 = Math.min(centerX + halfExpandLength, x + w);
  206. if (h2 > h1) {
  207. drawLine(ctx, h1, centerY, h2, centerY, 'black');
  208. }
  209. // Draw Vertical Line
  210. if (!expanded && (centerX < x + w)) {
  211. drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
  212. }
  213. }
  214. }
  215. let node = tree.items[options.row];
  216. let showTreeLine = true;
  217. if (!node) { return; }
  218. let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  219. let x1 = centerX + indent / 2;
  220. let centerY = Math.floor((y + (y + h)) / 2);
  221. let y1;
  222. // Draw Sibling Line
  223. if (showTreeLine) {
  224. // Draw Horizontal Line
  225. if (centerX < x + w) {
  226. drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
  227. let img;
  228. if(node.data.projType === projectType.folder){
  229. img = document.getElementById('folder_open_pic');
  230. imgWidth = 15;
  231. }
  232. else if(node.data.projType === projectType.project){
  233. img = document.getElementById('proj_pic');
  234. imgWidth = 18;
  235. }
  236. else if(node.data.projType === projectType.engineering){
  237. img = document.getElementById('eng_pic');
  238. imgWidth = 14;
  239. }
  240. else if(node.data.projType === projectType.tender){
  241. img = document.getElementById('tender_pic');
  242. imgWidth = 14;
  243. }
  244. ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
  245. }
  246. // Draw Vertical Line
  247. if (centerX < x + w) {
  248. y1 = node.isLast() ? centerY : y + h;
  249. if (node.isFirst() && !node.parent.parent) {
  250. drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
  251. } else {
  252. drawLine(ctx, centerX, y, centerX, y1, 'gray');
  253. }
  254. }
  255. }
  256. // Draw Expand Box
  257. if (node.children.length > 0) {
  258. drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
  259. }
  260. // Draw Parent Line
  261. if (showTreeLine) {
  262. var parent = node.parent, parentCenterX = centerX - indent - levelIndent;
  263. while (parent.parent) {
  264. if (!parent.isLast()) {
  265. if (parentCenterX < x + w) {
  266. drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
  267. }
  268. }
  269. parent = parent.parent;
  270. parentCenterX -= (indent + levelIndent);
  271. }
  272. };
  273. // Draw Text
  274. arguments[2] = x + (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3;
  275. arguments[4] = w - (node.depth() + 1) * indent - node.depth() * levelIndent - imgWidth - 3;
  276. GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
  277. };
  278. TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  279. let info = {x: x, y: y, row: context.row, col: context.col, cellStyle: cellStyle, cellRect: cellRect, sheetArea: context.sheetArea};
  280. let node = tree.items[info.row];
  281. let offset = -1;
  282. let centerX = info.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  283. let text = context.sheet.getText(info.row, info.col);
  284. let value = context.sheet.getValue(info.row, info.col);
  285. let acStyle = context.sheet.getActualStyle(info.row, info.col),
  286. zoom = context.sheet.zoom();
  287. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: context.sheet, row: info.row, col: info.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  288. if(info.x > centerX + halfBoxLength && info.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength){
  289. info.isReservedLocation = true;
  290. }
  291. return info;
  292. };
  293. TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
  294. let offset = -1;
  295. let node = tree.items[hitinfo.row];
  296. let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  297. let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
  298. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  299. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  300. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  301. zoom = hitinfo.sheet.zoom();
  302. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  303. //(图标+名字)区域
  304. function withingClickArea(){
  305. return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
  306. }
  307. //点击单位工程
  308. if(node.data.projType === projectType.tender && withingClickArea()){
  309. let newTab = window.open('about:blank');
  310. BeforeOpenProject(node.data.ID, {'fullFolder': GetFullFolder(node.parent)}, function () {
  311. let mainUrl = `/main?project=${node.data.ID}`;
  312. CommonAjax.get(mainUrl, [], function () {
  313. newTab.location.href = mainUrl;
  314. });
  315. });
  316. }
  317. if (!node || node.children.length === 0) { return; }
  318. if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
  319. node.setExpanded(!node.expanded);
  320. TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
  321. let iCount = node.posterityCount(), i, child;
  322. for (i = 0; i < iCount; i++) {
  323. child = tree.items[hitinfo.row + i + 1];
  324. hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
  325. }
  326. hitinfo.sheet.invalidateLayout();
  327. });
  328. hitinfo.sheet.repaint();
  329. }
  330. };
  331. TreeNodeCellType.prototype.processMouseMove = function (hitInfo) {
  332. let sheet = hitInfo.sheet;
  333. let div = sheet.getParent().getHost();
  334. let canvasId = div.id + "vp_vp";
  335. let canvas = $(`#${canvasId}`)[0];
  336. //改变鼠标图案
  337. if (sheet && hitInfo.isReservedLocation) {
  338. canvas.style.cursor='pointer';
  339. return true;
  340. }else{
  341. canvas.style.cursor='default';
  342. }
  343. return false;
  344. };
  345. TreeNodeCellType.prototype.processMouseEnter = function (hitinfo) {
  346. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  347. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  348. let tag = hitinfo.sheet.getTag(hitinfo.row, hitinfo.col);
  349. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  350. zoom = hitinfo.sheet.zoom();
  351. let node = tree.items[hitinfo.row];
  352. let nodeIndent = node ? (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3 : 0;
  353. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  354. let cellWidth = hitinfo.sheet.getCell(-1, hitinfo.col).width();
  355. if(textLength > cellWidth - nodeIndent){
  356. TREE_SHEET_HELPER.showTipsDiv(text,{pos: {}},hitinfo);
  357. }
  358. };
  359. TreeNodeCellType.prototype.processMouseLeave = function (hitinfo) {
  360. TREE_SHEET_HELPER.tipDiv = 'hide';
  361. if (TREE_SHEET_HELPER._toolTipElement) {
  362. $(TREE_SHEET_HELPER._toolTipElement).hide();
  363. TREE_SHEET_HELPER._toolTipElement = null;
  364. };
  365. TREE_SHEET_HELPER.tipDivCheck();//延时检查:当tips正在show的时候,就调用了hide方法,会导致tips一直存在,所以设置一个超时处理
  366. }
  367. return new TreeNodeCellType();
  368. }
  369. //
  370. //
  371. function getInteractionCell() {
  372. let InteractionCell = function () {
  373. };
  374. InteractionCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
  375. InteractionCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  376. return {
  377. x: x,
  378. y: y,
  379. row: context.row,
  380. col: context.col,
  381. cellStyle: cellStyle,
  382. cellRect: cellRect,
  383. sheetArea: context.sheetArea,
  384. isReservedLocation: true
  385. };
  386. };
  387. InteractionCell.prototype.processMouseDown = function (hitinfo) {
  388. let dataCode = headers[hitinfo.col]['dataCode'];
  389. let node = tree.items[hitinfo.row];
  390. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  391. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  392. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  393. zoom = hitinfo.sheet.zoom();
  394. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  395. if(hitinfo.x - hitinfo.cellRect.x > 0 && hitinfo.x - hitinfo.cellRect.x < textLength){
  396. //由..分享,弹出分享者信息
  397. if(dataCode === 'from'){
  398. if(node.data.shareType === shareType.receive){
  399. $('#userinfo').find('h4').text(node.data.userInfo.name);
  400. $('#userinfo').find('h6').text(node.data.userInfo.company);
  401. let mobileHtml = `<i class="fa fa-tablet"> ${node.data.userInfo.mobile ? node.data.userInfo.mobile : ''}</i>`;
  402. $('#userinfo').find('li:first-child').html(mobileHtml);
  403. let emailHtml = `<i class="fa fa-envelope-o"> ${node.data.userInfo.email ? node.data.userInfo.email : ''}</i>`;
  404. $('#userinfo').find('li:last-child').html(emailHtml);
  405. $('#userinfo').modal('show');
  406. }
  407. }
  408. //分享给
  409. else if(dataCode === 'to'){
  410. if(node.data.shareType === shareType.shareTo){
  411. setShareToModal(node);
  412. $('#shareTo').modal('show');
  413. }
  414. }
  415. //操作
  416. else if(dataCode === 'operation'){
  417. if(node.data.operation === '添加分享'){
  418. $('#sharePhone').val('');
  419. $('#share-info').hide();
  420. $('#share').find('.card').hide();
  421. $('#share').modal('show');
  422. $('#allowCopy').prop('checked', false);
  423. $('#allowCopyHint').hide();
  424. }
  425. else if(node.data.operation === '拷贝工程'){
  426. $('#copyShare').modal('show');
  427. }
  428. else {
  429. return;
  430. }
  431. }
  432. //清除
  433. else if(dataCode === 'delete'){
  434. gcTreeObj.oprProj('#delPoj', node)
  435. }
  436. //恢复单价文件
  437. else if(dataCode === 'unitPriceFile'){
  438. gcTreeObj.recoveryUnitPrc(node);
  439. }
  440. //清除单价文件
  441. else if(dataCode === 'unitPriceFile_delete'){
  442. gcTreeObj.deleteUnitPrc(node);
  443. }
  444. //恢复费率文件
  445. else if(dataCode === 'feeRateFile'){
  446. gcTreeObj.recoveryFeeRate(node);
  447. }
  448. //清除费率文件
  449. else if(dataCode === 'feeRateFile_delete'){
  450. gcTreeObj.deleteFeeRate(node);
  451. }
  452. }
  453. };
  454. InteractionCell.prototype.processMouseMove = function (hitInfo) {
  455. let dataCode = headers[hitInfo.col]['dataCode'];
  456. let node = tree.items[hitInfo.row];
  457. let sheet = hitInfo.sheet;
  458. let div = sheet.getParent().getHost();
  459. let canvasId = div.id + "vp_vp";
  460. let canvas = $(`#${canvasId}`)[0];
  461. //改变鼠标图案
  462. let text = hitInfo.sheet.getText(hitInfo.row, hitInfo.col);
  463. let value = hitInfo.sheet.getValue(hitInfo.row, hitInfo.col);
  464. let acStyle = hitInfo.sheet.getActualStyle(hitInfo.row, hitInfo.col),
  465. zoom = hitInfo.sheet.zoom();
  466. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitInfo.sheet, row: hitInfo.row, col: hitInfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  467. if (sheet && hitInfo.x - hitInfo.cellRect.x > 0 && hitInfo.x - hitInfo.cellRect.x < textLength) {
  468. canvas.style.cursor='pointer';
  469. return true;
  470. }else{
  471. canvas.style.cursor='default';
  472. }
  473. return false;
  474. };
  475. return new InteractionCell();
  476. }
  477. //设置分享给界面数据
  478. //@param {Object}selected @return {void}
  479. function setShareToModal(selected){
  480. $('#shareToInfo').empty();
  481. if(!selected){
  482. return;
  483. }
  484. let userIDs = [];
  485. for(let user of selected.data.shareInfo){
  486. userIDs.push(user.userID);
  487. }
  488. CommonAjax.post('/user/getUsers', {userIDs: userIDs}, function (rstData) {
  489. for(let userInfo of rstData){
  490. for(let user of selected.data.shareInfo){
  491. if(user.userID === userInfo._id){
  492. user.name = userInfo.real_name;
  493. user.company = userInfo.company;
  494. user.mobile = userInfo.mobile;
  495. user.email = userInfo.email;
  496. }
  497. }
  498. }
  499. let infoArr = [];
  500. for(let user of selected.data.shareInfo){
  501. let infoHtml = `<tr>
  502. <td style="width: 106px;">${user.name}</td>
  503. <td style="width: 146px;">${user.company}</td>
  504. <td style="width: 146px;">${user.mobile}</td>
  505. <td style="width: 156px;">${user.email}</td>
  506. <td style="width: 70px;text-align: center"><input value="allowCopy" ${user.allowCopy ? 'checked' : ''} type="checkbox"></td>
  507. <td style="width: 70px;text-align: center"><input value="cancelShare" type="checkbox"></td>
  508. </tr>`;
  509. infoArr.push(infoHtml);
  510. }
  511. let infoHtml = infoArr.join('');
  512. $('#shareToInfo').html(infoHtml);
  513. });
  514. }
  515. //更新项目分享信息
  516. //@param {Object}selected
  517. function updateShareInfo(selected){
  518. if(!selected){
  519. return;
  520. }
  521. let usersTr = $('#shareToInfo').find('tr');
  522. let newShareInfo = [];
  523. for(let i = 0; i < usersTr.length; i++){
  524. let userTr = usersTr[i];
  525. let allowCopy = $(userTr).find('input:first').prop('checked');
  526. let cancelShare = $(userTr).find('input:last').prop('checked');
  527. selected.data.shareInfo[i].allowCopy = allowCopy;
  528. if(!cancelShare){
  529. newShareInfo.push(selected.data.shareInfo[i]);
  530. }
  531. }
  532. CommonAjax.post('/pm/api/updateProjects', {user_id: userID, updateData: [{updateType: 'update', updateData: {ID: selected.data.ID, shareInfo: newShareInfo}}]}, function () {
  533. selected.data.shareInfo = newShareInfo;
  534. if(newShareInfo.length === 0){
  535. renderSheetFunc(spreadObj.sheet, function () {
  536. let rIdx = selected.serialNo();
  537. tree.removeNode(selected);
  538. spreadObj.sheet.deleteRows(rIdx, 1);
  539. spreadObj.sheet.setRowCount(tree.items);
  540. initSelection({row: spreadObj.sheet.getActiveRowIndex(), rowCount: 1},null);
  541. });
  542. }
  543. });
  544. }
  545. const foreColor = '#007bff';
  546. //显示树结构数据
  547. //@param {Array}nodes {Array}headers @return {void}
  548. function showTreeData(nodes, headers){
  549. let sheet = spreadObj.workBook.getActiveSheet();
  550. let fuc = function(){
  551. sheet.setRowCount(nodes.length);
  552. for(let i = 0; i < nodes.length; i++){
  553. let treeNodeCell = getTreeNodeCell(tree);
  554. sheet.getCell(i, 0).cellType(treeNodeCell);
  555. for(let j = 0; j < headers.length; j++){
  556. sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
  557. sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
  558. let dataCode = headers[j].dataCode;
  559. if(dataCode === 'operation'){
  560. let style = new GC.Spread.Sheets.Style();
  561. style.foreColor = foreColor;
  562. sheet.setStyle(i, j, style);
  563. sheet.getCell(i, j).cellType(getInteractionCell());
  564. }
  565. else if(dataCode === 'from'){
  566. if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.receive){
  567. let style = new GC.Spread.Sheets.Style();
  568. style.foreColor = foreColor;
  569. sheet.setStyle(i, j, style);
  570. sheet.getCell(i, j).cellType(getInteractionCell());
  571. }
  572. }
  573. else if(dataCode === 'to'){
  574. if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.shareTo){
  575. let style = new GC.Spread.Sheets.Style();
  576. style.foreColor = foreColor;
  577. sheet.setStyle(i, j, style);
  578. sheet.getCell(i, j).cellType(getInteractionCell());
  579. }
  580. }
  581. /* else if(dataCode === 'delete' || dataCode === 'unitPriceFile_delete' || dataCode === 'feeRateFile_delete'){
  582. let style = new GC.Spread.Sheets.Style();
  583. style.foreColor = me.setting.style.delForeColor;
  584. sheet.setStyle(-1, j, style);
  585. }*/
  586. sheet.setValue(i, j, nodes[i].data[dataCode] ? nodes[i].data[dataCode] : '');
  587. //me.setCellValue({row: i, col: j}, nodes[i]);
  588. }
  589. }
  590. };
  591. renderSheetFunc(sheet, fuc);
  592. }
  593. //将数据转换为可成树的数据,因为获取的数据不来自同一棵树
  594. //@param {Array}datas
  595. function buildTreeDatas(datas){
  596. let IDMap = {};
  597. for(let i = 0; i < datas.length; i++){
  598. let data = datas[i];
  599. let nextData = datas[i + 1];
  600. data.NextSiblingID = nextData ? nextData.ID : -1;
  601. data.ParentID = -1;
  602. IDMap[data.ID] = data;
  603. if(data.shareType === shareType.receive){
  604. if(data.userInfo){
  605. data.from = `由 ${data.userInfo.name} 分享`;
  606. data.to = '分享给 我';
  607. data.operation = isAllowCopy(userID, data) ? '拷贝工程' : '';
  608. }
  609. }
  610. else {
  611. data.from = '由 我 分享';
  612. data.to = '分享给...';
  613. data.operation = '添加分享';
  614. }
  615. }
  616. }
  617. //建立树
  618. //@return void
  619. function initShareTree(){
  620. $.bootstrapLoading.start();
  621. //获取分享数据
  622. CommonAjax.post('/pm/api/getShareProjects', {user_id: userID}, function (rstData) {
  623. let projDatas = rstData.receive.concat(rstData.share);
  624. buildTreeDatas(projDatas);
  625. tree = pmTree.createNew(treeSetting, projDatas);
  626. console.log(tree);
  627. tree.selected = tree.items[0];
  628. showTreeData(tree.items, headers);
  629. //初始选择
  630. let initSel = spreadObj.sheet.getSelections()[0] ? spreadObj.sheet.getSelections()[0] : {row: 0, rowCount: 1};
  631. initSelection(initSel);
  632. autoFlashHeight();
  633. spreadObj.workBook.refresh();
  634. $.bootstrapLoading.end();
  635. });
  636. }
  637. //初始化视图
  638. //@return void
  639. function initView(){
  640. if(tree){
  641. tree = null;
  642. }
  643. if(spreadObj.workBook){
  644. spreadObj.workBook.destroy();
  645. spreadObj.workBook = null;
  646. }
  647. buildSheet();
  648. initShareTree();
  649. }
  650. //根据建设项目获取单项工程
  651. //@param {Number}projID @return {void}
  652. function setEng(projID){
  653. let engQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: projectType.engineering, userID: userID, ParentID: projID};
  654. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: engQuery, options: '-_id -property'}, function (rstData) {
  655. $('#copyShare_selectEng').empty();
  656. for(let eng of rstData){
  657. let opt = $('<option>').val(eng.ID).text(eng.name);
  658. $('#copyShare_selectEng').append(opt);
  659. }
  660. });
  661. }
  662. //从其他建设项目中复制中,建设项目的文件层次结构名称和顺序
  663. //@param {Array}treeData @return {Array}
  664. function getFileHierarchyInfo(treeData){
  665. let tree = idTree.createNew({id: 'ID', pid: 'ParentID', nid: 'NextSiblingID', rootId: -1});
  666. tree.loadDatas(treeData);
  667. let items = tree.items;
  668. let rst = [];
  669. function getFileHierarchyName(node){
  670. let nodeName = node.data.name;
  671. let name = [];
  672. while (node.parent){
  673. name.push(node.parent.data.name ? node.parent.data.name : '');
  674. node = node.parent;
  675. }
  676. name = name.reverse();
  677. name.push(nodeName);
  678. return name.join('\\');
  679. }
  680. for(let node of items){
  681. if(node.children.length === 0 ){//project
  682. rst.push({ID: node.data.ID, fileHierarchyName: getFileHierarchyName(node)})
  683. }
  684. }
  685. return rst;
  686. }
  687. //设置拷贝工程下拉选择
  688. //@return {void}
  689. function setCopyModal(){
  690. //获取建设项目
  691. let projQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], projType: {$in: [projectType.project, projectType.folder]}, userID: userID};
  692. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: projQuery, options: '-_id -property'}, function (rstData) {
  693. let fileHierarchyData = getFileHierarchyInfo(rstData);
  694. $('#copyShare_selectProj').empty();
  695. for(let proj of fileHierarchyData){
  696. let opt = $('<option>').val(proj.ID).text(proj.fileHierarchyName);
  697. $('#copyShare_selectProj').append(opt);
  698. }
  699. //初始选择
  700. if(fileHierarchyData.length > 0){
  701. setEng(fileHierarchyData[0].ID);
  702. }
  703. });
  704. }
  705. //拷贝分享的工程
  706. //@param {Object}selected {Number}parentID @return {void}
  707. function copyShareProject(selected, projID, engID){
  708. if(!engID || !selected){
  709. return;
  710. }
  711. let copyMap = {copy: null, update: null};
  712. let newName = `${selected.data.name} (${selected.data.userInfo.name}分享拷贝)`;
  713. //获取单项工程的单位工程
  714. let tenderQuery = {$or: [{deleteInfo: null}, {'deleteInfo.deleted': false}], userID: userID, ParentID: engID};
  715. CommonAjax.post('/pm/api/getProjectsByQuery', {user_id: userID, query: tenderQuery, options: '-_id -property'}, function (rstData) {
  716. let updateTender = null;
  717. for(let tender of rstData){
  718. if(tender.name === newName){
  719. $('#copyShare_name').text('已存在此单位工程。');
  720. $('#copyShare_name').addClass('text-danger');
  721. return;
  722. }
  723. if(tender.NextSiblingID == -1){
  724. updateTender = tender;
  725. }
  726. }
  727. //更新前节点
  728. if(updateTender){
  729. copyMap.update = {query: {ID: updateTender.ID}};
  730. }
  731. //拷贝
  732. let copyData = {
  733. userID: userID,
  734. ID: selected.data.ID,
  735. NextSiblingID: -1,
  736. ParentID: engID,
  737. name: newName,
  738. shareInfo: [],
  739. compilation: selected.data.compilation,
  740. createDateTime: selected.data.createDateTime,
  741. fileVer: selected.data.fileVer ? selected.data.fileVer : '',
  742. projType: selected.data.projType,
  743. property: {},
  744. recentDateTime: selected.data.recentDateTime,
  745. fullFolder: selected.data.fullFolder
  746. };
  747. copyData.property.rootProjectID = projID;
  748. copyMap.copy = {document: copyData};
  749. $('#copyShare').modal('hide');
  750. $.bootstrapLoading.start();
  751. CommonAjax.post('/pm/api/copyProjects', {projectMap: copyMap, user_id: userID}, function (rstData) {
  752. $.bootstrapLoading.end();
  753. }, function () {
  754. $.bootstrapLoading.end();
  755. });
  756. });
  757. }
  758. //事件监听器
  759. //@return void
  760. function eventListener(){
  761. //tab
  762. $('#tab_pm_share').on('shown.bs.tab', function () {
  763. //侧滑隐藏
  764. $('.slide-sidebar').removeClass('open');
  765. $('.slide-sidebar').css('width', '0');
  766. projTreeObj.tree = null;
  767. if(projTreeObj.workBook){
  768. projTreeObj.workBook.destroy();
  769. projTreeObj.workBook = null;
  770. }
  771. gcTreeObj.tree = null;
  772. if(gcTreeObj.workBook){
  773. gcTreeObj.workBook.destroy();
  774. gcTreeObj.workBook = null;
  775. }
  776. initView();
  777. });
  778. //关闭拷贝工程
  779. $('#copyShare').on('hidden.bs.modal', function () {
  780. $('#copyShareProj-info').hide();
  781. $('#copyShareEng-info').hide();
  782. });
  783. //打开拷贝工程
  784. $('#copyShare').on('shown.bs.modal', function () {
  785. setCopyModal();
  786. //更改显示名称
  787. let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
  788. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  789. $('#copyShare_name').removeClass('text-danger');
  790. });
  791. //拷贝工程改变选择建设项目
  792. $('#copyShare_selectProj').change(function () {
  793. //更改显示名称
  794. let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
  795. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  796. $('#copyShare_name').removeClass('text-danger');
  797. $('#copyShareProj-info').hide();
  798. $('#copyShareEng-info').hide();
  799. let curSelID = $(this).select().val();
  800. setEng(parseInt(curSelID));
  801. });
  802. //拷贝工程改变选择单项工程
  803. $('#copyShare_selectEng').change(function () {
  804. //更改显示名称
  805. let newName = `${shareSeleted.data.name} (${shareSeleted.data.userInfo.name}分享拷贝)`;
  806. $('#copyShare_name').html(`拷贝后,工程将重命名为 "<b>${newName}</b>"`);
  807. $('#copyShare_name').removeClass('text-danger');
  808. });
  809. //确认拷贝
  810. $('#copyShare_confirm').click(function () {
  811. let selProj = $('#copyShare_selectProj').select().val();
  812. if(!selProj){
  813. $('#copyShareProj-info').show();
  814. return;
  815. }
  816. let selEng = $('#copyShare_selectEng').select().val();
  817. if(!selEng){
  818. $('#copyShareEng-info').show();
  819. return;
  820. }
  821. copyShareProject(tree.selected, parseInt(selProj), parseInt(selEng));
  822. });
  823. //分享给...界面确认
  824. $('#shareToConfirm').click(function () {
  825. updateShareInfo(tree.selected);
  826. });
  827. }
  828. return {spreadObj, headers, initView, eventListener}
  829. })();
  830. $(document).ready(function () {
  831. pmShare.eventListener();
  832. });