|  | @@ -16,7 +16,8 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |      const shareType = {receive: 'receive', shareTo: 'shareTo'};
 | 
	
		
			
				|  |  |      //操作类型
 | 
	
		
			
				|  |  |      const oprType = {copy: 'copy', cancel: 'cancel'};
 | 
	
		
			
				|  |  | -    let tree = null;
 | 
	
		
			
				|  |  | +    let tree = null,
 | 
	
		
			
				|  |  | +        actualIDShareInfo = {};//项目真实树ID与项目分享信息映射
 | 
	
		
			
				|  |  |      const treeCol = 0;
 | 
	
		
			
				|  |  |      const treeSetting = {
 | 
	
		
			
				|  |  |          tree: {
 | 
	
	
		
			
				|  | @@ -29,9 +30,8 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |      const headers = [
 | 
	
		
			
				|  |  |          {name: '工程列表', dataCode: 'name', width: 300, rateWidth: 0.55, vAlign: 'center', hAlign: 'left'},
 | 
	
		
			
				|  |  | -        {name: '由...分享', dataCode: 'from', width: 120, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
 | 
	
		
			
				|  |  | -     /*   {name: '拷贝工程', dataCode: 'copy', width: 100, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},
 | 
	
		
			
				|  |  | -        {name: '清除', dataCode: 'cancel', width: 100, rateWidth: 0.075, vAlign: 'center', hAlign: 'left'},*/
 | 
	
		
			
				|  |  | +        {name: '来自', dataCode: 'from', width: 80, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
 | 
	
		
			
				|  |  | +        {name: '分享时间', dataCode: 'shareDate', width: 140, rateWidth: 0.15, vAlign: 'center', hAlign: 'left'},
 | 
	
		
			
				|  |  |          {name: '工程造价', dataCode: 'engineeringCost', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
 | 
	
		
			
				|  |  |          {name: '分部分项合计', dataCode: 'subEngineering', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
 | 
	
		
			
				|  |  |          {name: '措施项目合计', dataCode: 'measure', width: 100, vAlign: 'center', hAlign: 'right', formatter: '0.00'},
 | 
	
	
		
			
				|  | @@ -125,12 +125,6 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |                  if(headers[i].formatter){
 | 
	
		
			
				|  |  |                      sheet.setFormatter(-1, i, headers[i].formatter);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -              /*  if(headers[i].dataCode === oprType.copy){
 | 
	
		
			
				|  |  | -                    //合并列
 | 
	
		
			
				|  |  | -                    sheet.addSpan(0, i, 1, 2, GC.Spread.Sheets.SheetArea.colHeader);
 | 
	
		
			
				|  |  | -                    sheet.setValue(0, i, '操作', GC.Spread.Sheets.SheetArea.colHeader);
 | 
	
		
			
				|  |  | -                    continue;
 | 
	
		
			
				|  |  | -                }*/
 | 
	
		
			
				|  |  |                  sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
 | 
	
		
			
				|  |  |                  sheet.getRange(-1, i, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[i]['hAlign']]);
 | 
	
		
			
				|  |  |                  sheet.getRange(-1, i, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[i]['vAlign']]);
 | 
	
	
		
			
				|  | @@ -162,15 +156,56 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |          spreadObj.sheet.getRange(-1, -1, -1, -1).locked(true);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    //此项目的分享权限信息(可能会被父级项目覆盖,以新为准)
 | 
	
		
			
				|  |  | +    //@param {String}userID(本用户id) {Object}project(项目) @return {Object} || {Null}
 | 
	
		
			
				|  |  | +    function getShareInfo(userID, project) {
 | 
	
		
			
				|  |  | +        if (!project.actualTreeInfo) {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //获取跟本用户和选中项目相关的分享信息
 | 
	
		
			
				|  |  | +        let shareList = [];
 | 
	
		
			
				|  |  | +        let actualID = project.actualTreeInfo.ID,
 | 
	
		
			
				|  |  | +            actualData = actualIDShareInfo[actualID];
 | 
	
		
			
				|  |  | +        while (actualData) {
 | 
	
		
			
				|  |  | +            for (let data of actualData.shareInfo) {
 | 
	
		
			
				|  |  | +                if (data.userID === userID) {
 | 
	
		
			
				|  |  | +                    shareList.push(data);
 | 
	
		
			
				|  |  | +                    break;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            actualData = actualIDShareInfo[actualData.ParentID];
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //获取最新分享
 | 
	
		
			
				|  |  | +        shareList.sort(function (a, b) {
 | 
	
		
			
				|  |  | +            let aV = Date.parse(a.shareDate),
 | 
	
		
			
				|  |  | +                bV = Date.parse(b.shareDate);
 | 
	
		
			
				|  |  | +            if (aV > bV) {
 | 
	
		
			
				|  |  | +                return -1;
 | 
	
		
			
				|  |  | +            } else if (aV < bV) {
 | 
	
		
			
				|  |  | +                return 1;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return 0;
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        return shareList[0] || null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      //此项目是否可以拷贝
 | 
	
		
			
				|  |  |      //@param {String}userID {Object}project @return {Boolean}
 | 
	
		
			
				|  |  |      function isAllowCopy(userID, project){
 | 
	
		
			
				|  |  | -        for(let shareData of project.shareInfo){
 | 
	
		
			
				|  |  | -            if(shareData.userID === userID){
 | 
	
		
			
				|  |  | -                return shareData.allowCopy;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +        let myShareInfo = getShareInfo(userID, project);
 | 
	
		
			
				|  |  | +        if (!myShareInfo) {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return !!myShareInfo.allowCopy;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    //此项目是否可以协作
 | 
	
		
			
				|  |  | +    //@param {String}userID {Object}project @return {Boolean}
 | 
	
		
			
				|  |  | +    function isAllowCoop(userID, project) {
 | 
	
		
			
				|  |  | +        let myShareInfo = getShareInfo(userID, project);
 | 
	
		
			
				|  |  | +        if (!myShareInfo) {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        return !!myShareInfo.allowCooperate;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      //获取树节点
 | 
	
		
			
				|  |  |      //@param {Object}tree @return {Object}
 | 
	
	
		
			
				|  | @@ -398,9 +433,44 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      //互动单元格
 | 
	
		
			
				|  |  |      function getInteractionCell() {
 | 
	
		
			
				|  |  | +        let workImg = document.getElementById('work_pic'),
 | 
	
		
			
				|  |  | +            workImgWidth = 13,
 | 
	
		
			
				|  |  | +            workImgHeight = 13,
 | 
	
		
			
				|  |  | +            copyImg = document.getElementById('copy_pic'),
 | 
	
		
			
				|  |  | +            copyImgWidth = 13,
 | 
	
		
			
				|  |  | +            copyImgHeight = 13;
 | 
	
		
			
				|  |  |          let InteractionCell = function () {
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          InteractionCell.prototype = new GC.Spread.Sheets.CellTypes.Text();
 | 
	
		
			
				|  |  | +        InteractionCell.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
 | 
	
		
			
				|  |  | +            if (style.backColor) {
 | 
	
		
			
				|  |  | +                ctx.save();
 | 
	
		
			
				|  |  | +                ctx.fillStyle = style.backColor;
 | 
	
		
			
				|  |  | +                ctx.fillRect(x, y, w, h);
 | 
	
		
			
				|  |  | +                ctx.restore();
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                ctx.clearRect(x, y, w, h);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            let node = tree.items[options.row];
 | 
	
		
			
				|  |  | +            // Draw Text
 | 
	
		
			
				|  |  | +            GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
 | 
	
		
			
				|  |  | +            if (node && node.data.projType === projectType.tender) {
 | 
	
		
			
				|  |  | +                let text = options.sheet.getText(options.row, options.col);
 | 
	
		
			
				|  |  | +                let acStyle = options.sheet.getActualStyle(options.row, options.col),
 | 
	
		
			
				|  |  | +                    zoom = options.sheet.zoom();
 | 
	
		
			
				|  |  | +                let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: options.sheet, row: options.row, col: options.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
 | 
	
		
			
				|  |  | +                let nowX  = Math.floor(x) + textLength + 3,
 | 
	
		
			
				|  |  | +                    nowY = Math.floor((y + (y + h)) / 2) - 7;
 | 
	
		
			
				|  |  | +                if (node.data.allowCooperate) {
 | 
	
		
			
				|  |  | +                    ctx.drawImage(workImg, nowX, nowY, workImgWidth, workImgHeight);
 | 
	
		
			
				|  |  | +                    nowX += workImgWidth;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (node.data.allowCopy) {
 | 
	
		
			
				|  |  | +                    ctx.drawImage(copyImg, nowX, nowY, copyImgWidth, copyImgHeight);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  |          InteractionCell.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
 | 
	
		
			
				|  |  |              return {
 | 
	
		
			
				|  |  |                  x: x,
 | 
	
	
		
			
				|  | @@ -434,36 +504,6 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |                          $('#userinfo').modal('show');
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                //分享给
 | 
	
		
			
				|  |  | -                else if(dataCode === 'to'){
 | 
	
		
			
				|  |  | -                    if(node.data.shareType === shareType.shareTo){
 | 
	
		
			
				|  |  | -                        setShareToModal(node);
 | 
	
		
			
				|  |  | -                        $('#shareTo').modal('show');
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                //操作
 | 
	
		
			
				|  |  | -                else if(dataCode === oprType.copy){
 | 
	
		
			
				|  |  | -                   /* if(node.data.copy === '添加分享'){
 | 
	
		
			
				|  |  | -                        $('#sharePhone').val('');
 | 
	
		
			
				|  |  | -                        $('#share-info').hide();
 | 
	
		
			
				|  |  | -                        $('#share').find('.card').hide();
 | 
	
		
			
				|  |  | -                        $('#share').modal('show');
 | 
	
		
			
				|  |  | -                        $('#allowCopy').prop('checked', false);
 | 
	
		
			
				|  |  | -                        $('#allowCopyHint').hide();
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    else*/
 | 
	
		
			
				|  |  | -                    if(node.data.copy === '拷贝工程'){
 | 
	
		
			
				|  |  | -                        $('#copyShare').modal('show');
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else if (dataCode === oprType.cancel) {
 | 
	
		
			
				|  |  | -                    if (node.data.cancel === '清除') {
 | 
	
		
			
				|  |  | -                        let $p = $('<p>').text(`点“确定”按钮,确认清除分享文件 “${node.data.name}”。`);
 | 
	
		
			
				|  |  | -                        $('#cancelShare').find('.modal-body').empty();
 | 
	
		
			
				|  |  | -                        $('#cancelShare').find('.modal-body').append($p);
 | 
	
		
			
				|  |  | -                        $('#cancelShare').modal('show');
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          InteractionCell.prototype.processMouseMove = function (hitInfo) {
 | 
	
	
		
			
				|  | @@ -573,45 +613,28 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |                      sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
 | 
	
		
			
				|  |  |                      sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
 | 
	
		
			
				|  |  |                      let dataCode = headers[j].dataCode;
 | 
	
		
			
				|  |  | -                    if(dataCode === oprType.copy){
 | 
	
		
			
				|  |  | +                    if(dataCode === 'from'){
 | 
	
		
			
				|  |  |                          let style = new GC.Spread.Sheets.Style();
 | 
	
		
			
				|  |  |                          style.foreColor = foreColor;
 | 
	
		
			
				|  |  |                          sheet.setStyle(i, j, style);
 | 
	
		
			
				|  |  |                          sheet.getCell(i, j).cellType(getInteractionCell());
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    else if (dataCode === oprType.cancel) {
 | 
	
		
			
				|  |  | -                        let style = new GC.Spread.Sheets.Style();
 | 
	
		
			
				|  |  | -                        style.foreColor = cancelForeColor;
 | 
	
		
			
				|  |  | -                        sheet.setStyle(i, j, style);
 | 
	
		
			
				|  |  | -                        sheet.getCell(i, j).cellType(getInteractionCell());
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    else if(dataCode === 'from'){
 | 
	
		
			
				|  |  | -                        if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.receive){
 | 
	
		
			
				|  |  | -                            let style = new GC.Spread.Sheets.Style();
 | 
	
		
			
				|  |  | -                            style.foreColor = foreColor;
 | 
	
		
			
				|  |  | -                            sheet.setStyle(i, j, style);
 | 
	
		
			
				|  |  | -                            sheet.getCell(i, j).cellType(getInteractionCell());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    else if(dataCode === 'to'){
 | 
	
		
			
				|  |  | -                        if(nodes[i].data.shareType && nodes[i].data.shareType === shareType.shareTo){
 | 
	
		
			
				|  |  | -                            let style = new GC.Spread.Sheets.Style();
 | 
	
		
			
				|  |  | -                            style.foreColor = foreColor;
 | 
	
		
			
				|  |  | -                            sheet.setStyle(i, j, style);
 | 
	
		
			
				|  |  | -                            sheet.getCell(i, j).cellType(getInteractionCell());
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  |                      sheet.setValue(i, j, nodes[i].data[dataCode] !== null && typeof nodes[i].data[dataCode] !== 'undefined' ? nodes[i].data[dataCode] : '');
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          renderSheetFunc(sheet, fuc);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    //同一棵树,可能存在相同数据显示多条的问题(传入的datas中不存在相同数据),将真实树结构数据存在actualTreeInfo中,外部树结构数据用uuid重置。
 | 
	
		
			
				|  |  | +    //同一棵树,可能存在相同数据显示多条的问题(传入的datas中不存在相同数据)
 | 
	
		
			
				|  |  | +    //将真实树结构数据存在actualTreeInfo中,外部树结构数据用uuid重置。
 | 
	
		
			
				|  |  |      //@param {Array}datas
 | 
	
		
			
				|  |  |      function setTreeInfo(datas) {
 | 
	
		
			
				|  |  |          let IDMapping = {};
 | 
	
		
			
				|  |  |          for (let data of datas) {
 | 
	
		
			
				|  |  | +            //项目真实ID与项目分享信息映射,方便确定项目的权限
 | 
	
		
			
				|  |  | +            if (!actualIDShareInfo[data.ID]) {
 | 
	
		
			
				|  |  | +                actualIDShareInfo[data.ID] = {ID: data.ID, ParentID: data.ParentID, NextSiblingID: data.NextSiblingID, shareInfo: data.shareInfo};
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              IDMapping[data.ID] = uuid.v1();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          for (let data of datas) {
 | 
	
	
		
			
				|  | @@ -631,21 +654,17 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |              data.ParentID = pid;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    //给项目设置分享信息:由xx分享、分享给我、可进行的操作,含有userInfo信息的文件为他人直接分享的文件,他人分享父级文件,子文件不含有userInfo信息
 | 
	
		
			
				|  |  | +    //给项目设置分享信息:由xx分享、分享时间、分享给我,含有userInfo信息的文件为他人直接分享的文件,他人分享父级文件,子文件不含有userInfo信息
 | 
	
		
			
				|  |  |      //@param {Array}datas @return {void}
 | 
	
		
			
				|  |  |      function setShareInfo(datas) {
 | 
	
		
			
				|  |  |          for (let data of datas) {
 | 
	
		
			
				|  |  |              if (data.userInfo) {
 | 
	
		
			
				|  |  | -                data.from = `由 ${data.userInfo.name} 分享`;
 | 
	
		
			
				|  |  | +                //shareInfo中我的条目
 | 
	
		
			
				|  |  | +                let selfInfo = _.find(data.shareInfo, {userID: userID});
 | 
	
		
			
				|  |  | +                data.shareDate = selfInfo ? selfInfo.shareDate : ''
 | 
	
		
			
				|  |  | +                data.from = data.userInfo.name;
 | 
	
		
			
				|  |  |                  data.to = '分享给 我';
 | 
	
		
			
				|  |  |                  data.cancel = '清除';
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                //拷贝操作只允许到单位工程级
 | 
	
		
			
				|  |  | -                let tendersCanCopy = isAllowCopy(userID, data);
 | 
	
		
			
				|  |  | -                let tenders = data.projType === projectType.tender ? [data] : _.filter(data.children, {projType: projectType.tender});
 | 
	
		
			
				|  |  | -                for (let tender of tenders) {
 | 
	
		
			
				|  |  | -                    tender.copy = tendersCanCopy ? '拷贝工程' : '';
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -678,6 +697,30 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    //从同层树数据获取第一个节点ID
 | 
	
		
			
				|  |  | +    //@param {Array}treeDatas树的数据 @return {String}第一个节点的虚拟树ID
 | 
	
		
			
				|  |  | +    function getFirstID(treeDatas) {
 | 
	
		
			
				|  |  | +        let treeMapping = {};
 | 
	
		
			
				|  |  | +        //建立ID索引
 | 
	
		
			
				|  |  | +        for (let data of treeDatas) {
 | 
	
		
			
				|  |  | +            //新建一个简单对象,防止污染treeDatas的数据
 | 
	
		
			
				|  |  | +            treeMapping[data.ID] = {ID: data.ID, prev: null, next: null};
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //绑定prev next
 | 
	
		
			
				|  |  | +        for (let data of treeDatas) {
 | 
	
		
			
				|  |  | +            let me =  treeMapping[data.ID],
 | 
	
		
			
				|  |  | +                next = treeMapping[data.NextSiblingID];
 | 
	
		
			
				|  |  | +            if (next) {
 | 
	
		
			
				|  |  | +                me.next = next;
 | 
	
		
			
				|  |  | +                next.prev = me;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //返回没有prev属性的数据
 | 
	
		
			
				|  |  | +        let result = _.find(treeDatas, function (data) {
 | 
	
		
			
				|  |  | +            return !treeMapping[data.ID].prev
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        return  result ? result.ID : -1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      //获取可成树的数据
 | 
	
		
			
				|  |  |      //@param {Array}datas @return {Array}
 | 
	
		
			
				|  |  |      function getTreeDatas(groupedDatas, ungroupedDatas){
 | 
	
	
		
			
				|  | @@ -694,12 +737,14 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |          let rst = [];
 | 
	
		
			
				|  |  |          //整理树结构
 | 
	
		
			
				|  |  |          sortSameDepthData(groupedDatas, -1);
 | 
	
		
			
				|  |  | +        //第一个根节点数据
 | 
	
		
			
				|  |  | +        let firstID = getFirstID(groupedDatas);
 | 
	
		
			
				|  |  |          //新建未分类建设项目及单项工程
 | 
	
		
			
				|  |  | -        let ungroupedProj = {ID: uuid.v1(), ParentID: -1, NextSiblingID: -1, name: '未分类建设项目', projType: projectType.project};
 | 
	
		
			
				|  |  | +        let ungroupedProj = {ID: uuid.v1(), ParentID: -1, NextSiblingID: firstID, name: '未分类建设项目', projType: projectType.project};
 | 
	
		
			
				|  |  |          let ungroupedEng = {ID: uuid.v1(), ParentID: ungroupedProj.ID, NextSiblingID: -1, name: '未分类单项工程', projType: projectType.engineering};
 | 
	
		
			
				|  |  | -        if (groupedDatas.length > 0) {
 | 
	
		
			
				|  |  | +        /*if (groupedDatas.length > 0) {
 | 
	
		
			
				|  |  |              groupedDatas[groupedDatas.length - 1].NextSiblingID = ungroupedProj.ID;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        }*/
 | 
	
		
			
				|  |  |          //将未分类的数据归类
 | 
	
		
			
				|  |  |          sortSameDepthData(engs, ungroupedProj.ID);
 | 
	
		
			
				|  |  |          sortSameDepthData(tenders, ungroupedEng.ID);
 | 
	
	
		
			
				|  | @@ -735,6 +780,19 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |              return 0;
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +    //设置节点数据权限
 | 
	
		
			
				|  |  | +    //@param {Array}datas项目数据
 | 
	
		
			
				|  |  | +    function setPermissionsInfo(datas) {
 | 
	
		
			
				|  |  | +        //data.allowCopy与shareInfo里allowCopy的区别:
 | 
	
		
			
				|  |  | +        //data.allowCopy为该单位实际的权限(跟着最新的分享信息走,可能随着父项)
 | 
	
		
			
				|  |  | +        for (let data of datas) {
 | 
	
		
			
				|  |  | +            if (data.projType === projectType.tender) {
 | 
	
		
			
				|  |  | +                data.allowCopy = isAllowCopy(userID, data);
 | 
	
		
			
				|  |  | +                data.allowCooperate = isAllowCoop(userID, data);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      //建立树
 | 
	
		
			
				|  |  |      //@return void
 | 
	
		
			
				|  |  |      function initShareTree(){
 | 
	
	
		
			
				|  | @@ -750,6 +808,7 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |                  setSummaryInfo(rstData.ungrouped, rstData.summaryInfo.ungrouped);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              let treeDatas = getTreeDatas(rstData.grouped, rstData.ungrouped);
 | 
	
		
			
				|  |  | +            setPermissionsInfo(treeDatas);
 | 
	
		
			
				|  |  |              tree = pmTree.createNew(treeSetting, treeDatas);
 | 
	
		
			
				|  |  |              tree.selected = tree.items[0];
 | 
	
		
			
				|  |  |              showTreeData(tree.items, headers);
 | 
	
	
		
			
				|  | @@ -777,7 +836,7 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |                      icon: 'fa-copy',
 | 
	
		
			
				|  |  |                      disabled: function () {
 | 
	
		
			
				|  |  |                          let selected = tree.selected;
 | 
	
		
			
				|  |  | -                        return !(selected && selected.data.copy && selected.data.copy === '拷贝工程');
 | 
	
		
			
				|  |  | +                        return !(selected && selected.data.allowCopy);
 | 
	
		
			
				|  |  |                      },
 | 
	
		
			
				|  |  |                      callback: function (key, opt) {
 | 
	
		
			
				|  |  |                          $('#copyShare').modal('show');
 | 
	
	
		
			
				|  | @@ -1001,12 +1060,42 @@ const pmShare = (function () {
 | 
	
		
			
				|  |  |              copyShareProject(tree.selected, parseInt(selProj), parseInt(selEng));
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |          //清除分享
 | 
	
		
			
				|  |  | +        //清除了该节点后,可能还有该节点的数据在树上(树允许有重复数据),需要更新分享信息
 | 
	
		
			
				|  |  | +        function updateAfterCancel(userID, projectID) {
 | 
	
		
			
				|  |  | +            for (let item of tree.items) {
 | 
	
		
			
				|  |  | +                if (item.data.actualTreeInfo && item.data.actualTreeInfo.ID === projectID) {
 | 
	
		
			
				|  |  | +                    _.remove(item.data.shareInfo, function (data) {
 | 
	
		
			
				|  |  | +                        return data.userID === userID;
 | 
	
		
			
				|  |  | +                    });
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          $('#cancelShareConfirm').click(function () {
 | 
	
		
			
				|  |  |              $.bootstrapLoading.start();
 | 
	
		
			
				|  |  | -            CommonAjax.post('/pm/api/share', {user_id: userID, type: oprType.cancel,  projectID: tree.selected.data.actualTreeInfo.ID, shareData:[{userID: userID}]}, function (rstData) {
 | 
	
		
			
				|  |  | -                $.bootstrapLoading.end();
 | 
	
		
			
				|  |  | +            let cancelProjID = tree.selected.data.actualTreeInfo.ID;
 | 
	
		
			
				|  |  | +            CommonAjax.post('/pm/api/share', {user_id: userID, type: oprType.cancel,  projectID: cancelProjID, shareData:[{userID: userID}]}, function (rstData) {
 | 
	
		
			
				|  |  |                  tree.removeNode(tree.selected);
 | 
	
		
			
				|  |  | +                //更新与清除节点数据相同,且为被清除缓存分享信息
 | 
	
		
			
				|  |  | +                updateAfterCancel(userID, cancelProjID);
 | 
	
		
			
				|  |  | +                //重新设置actualIDShareInfo,以正确更新权限(清除了分享信息后,可能会导致权限变化 eg:清除了新的分享,则存留的分享项目采用旧的)
 | 
	
		
			
				|  |  | +                actualIDShareInfo = {};
 | 
	
		
			
				|  |  | +                let treeDatas = [];
 | 
	
		
			
				|  |  | +                for (let item of tree.items) {
 | 
	
		
			
				|  |  | +                    treeDatas.push(item.data);
 | 
	
		
			
				|  |  | +                    let actualTreeInfo = item.data.actualTreeInfo;
 | 
	
		
			
				|  |  | +                    if (actualTreeInfo && !actualIDShareInfo[actualTreeInfo.ID]) {
 | 
	
		
			
				|  |  | +                        actualIDShareInfo[actualTreeInfo.ID] = {
 | 
	
		
			
				|  |  | +                            ID: actualTreeInfo.ID,
 | 
	
		
			
				|  |  | +                            ParentID: actualTreeInfo.ParentID,
 | 
	
		
			
				|  |  | +                            NextSiblingID: actualTreeInfo.NextSiblingID,
 | 
	
		
			
				|  |  | +                            shareInfo: item.data.shareInfo
 | 
	
		
			
				|  |  | +                        };
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                //重新设置权限
 | 
	
		
			
				|  |  | +                setPermissionsInfo(treeDatas);
 | 
	
		
			
				|  |  |                  showTreeData(tree.items, headers);
 | 
	
		
			
				|  |  | +                $.bootstrapLoading.end();
 | 
	
		
			
				|  |  |              }, function () {
 | 
	
		
			
				|  |  |                  $.bootstrapLoading.end();
 | 
	
		
			
				|  |  |              });
 |