|  | @@ -139,8 +139,10 @@ var feeRateObject={
 | 
	
		
			
				|  |  |          feeRateObject.feeRateSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick,feeRateObject.onCellDoubleClick);
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      showFeeRateTree:function (sheet,setting,data) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          let ch = GC.Spread.Sheets.SheetArea.viewport;
 | 
	
		
			
				|  |  | -        let parentMap=_.indexBy(data, 'ParentID');
 | 
	
		
			
				|  |  | +        let parentMap=_.groupBy(data, 'ParentID');
 | 
	
		
			
				|  |  | +        let visibleMap = {};
 | 
	
		
			
				|  |  |          sheet.suspendPaint();
 | 
	
		
			
				|  |  |          sheet.suspendEvent();
 | 
	
		
			
				|  |  |          for (let col = 0; col < setting.header.length; col++) {
 | 
	
	
		
			
				|  | @@ -168,18 +170,13 @@ var feeRateObject={
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  sheet.setValue(row, col, val, ch);
 | 
	
		
			
				|  |  |                  if(col==0){
 | 
	
		
			
				|  |  | -                    sheet.getCell(row, 0).textIndent(feeRateObject.getFeeRateLevel(data[row],data));//设置层级,0 为第一层
 | 
	
		
			
				|  |  | +                    let treeType = feeRateObject.getTreeNodeCellType(data,row,parentMap);
 | 
	
		
			
				|  |  | +                    sheet.getCell(row, 0).cellType(treeType);
 | 
	
		
			
				|  |  | +                    visibleMap[data[row].ID] = treeType.collapsed;
 | 
	
		
			
				|  |  | +                    if(visibleMap[data[row].ParentID] ) sheet.getRange(row , -1, 1, -1).visible(false);//显示或隐藏
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        sheet.outlineColumn.options({columnIndex: 0, maxLevel: 10});//设置树结构显示的列,和最大层级
 | 
	
		
			
				|  |  | -        for(let i =0;i<data.length;i++){
 | 
	
		
			
				|  |  | -            if(parentMap[data[i].ID]){
 | 
	
		
			
				|  |  | -                sheet.rowOutlines.setCollapsed(i, true);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        sheet.showRowOutline(false);
 | 
	
		
			
				|  |  | -        sheet.outlineColumn.refresh();
 | 
	
		
			
				|  |  |          sheet.resumeEvent();
 | 
	
		
			
				|  |  |          sheet.resumePaint();
 | 
	
		
			
				|  |  |      },
 | 
	
	
		
			
				|  | @@ -212,52 +209,63 @@ var feeRateObject={
 | 
	
		
			
				|  |  |          feeRateObject.onCellClick({type: 'CellClick'}, {row:rowIdx});
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          function expandParent(ID,datas,sheet) {//递归展开父节点
 | 
	
		
			
				|  |  | -            let index = _.findIndex(datas,{'ID':ID});
 | 
	
		
			
				|  |  | -            sheet.rowOutlines.setCollapsed(index, false);
 | 
	
		
			
				|  |  | -            if(datas[index].ParentID){
 | 
	
		
			
				|  |  | -                expandParent(datas[index].ParentID,datas,sheet)
 | 
	
		
			
				|  |  | +             let cellType = setCollapsed(ID);
 | 
	
		
			
				|  |  | +             cellType.refreshChildrenVisible(sheet);
 | 
	
		
			
				|  |  | +            function setCollapsed(parentID){
 | 
	
		
			
				|  |  | +                let index = _.findIndex(datas,{'ID':parentID});
 | 
	
		
			
				|  |  | +                let type = sheet.getCellType(index,0);
 | 
	
		
			
				|  |  | +                type.collapsed = false;
 | 
	
		
			
				|  |  | +                if(datas[index].ParentID){
 | 
	
		
			
				|  |  | +                    setCollapsed(datas[index].ParentID)
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                return type
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    getTreeNodeCellType:function () {//这个方法费率已暂时不用了
 | 
	
		
			
				|  |  | +    getTreeNodeCellType:function (datas,row,parentMap) {// 2018-09-26  不用spreadjs默认的树结构,自定义控件
 | 
	
		
			
				|  |  |          var ns = GC.Spread.Sheets;
 | 
	
		
			
				|  |  | +        let rectW = 10;
 | 
	
		
			
				|  |  | +        let rectH = 10;
 | 
	
		
			
				|  |  | +        let margin = 3;
 | 
	
		
			
				|  |  |          function TreeNodeCellType() {
 | 
	
		
			
				|  |  | +            this.collapsed = true; //默认是折叠的
 | 
	
		
			
				|  |  | +            this.rectInfo = {};
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          TreeNodeCellType.prototype = new ns.CellTypes.Text();
 | 
	
		
			
				|  |  |          TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
 | 
	
		
			
				|  |  | -            var level = options.sheet.rowOutlines.getLevel(options.row);
 | 
	
		
			
				|  |  | -            var nlevel = -1;
 | 
	
		
			
				|  |  | -            if (options.row < options.sheet.getRowCount() - 1) {
 | 
	
		
			
				|  |  | -                nlevel = options.sheet.rowOutlines.getLevel(options.row + 1);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            var hoffset = (level + 2) * 12;
 | 
	
		
			
				|  |  | -            x += hoffset;
 | 
	
		
			
				|  |  | -            w -= hoffset;
 | 
	
		
			
				|  |  | -            GC.Spread.Sheets.CellTypes.Base.prototype.paint.apply(this, arguments);
 | 
	
		
			
				|  |  | -            if (options.row == options.sheet.getRowCount() - 1) return; //last row
 | 
	
		
			
				|  |  | -            if (nlevel > level) {
 | 
	
		
			
				|  |  | -                var collapsed = options.sheet.rowOutlines.isCollapsed(options.row + 1);
 | 
	
		
			
				|  |  | -                x--;
 | 
	
		
			
				|  |  | -                y += h / 2 - 3;
 | 
	
		
			
				|  |  | -                ctx.save();
 | 
	
		
			
				|  |  | -                ctx.fillStyle = "black";
 | 
	
		
			
				|  |  | -                ctx.beginPath();
 | 
	
		
			
				|  |  | -                if (collapsed) {
 | 
	
		
			
				|  |  | -                    ctx.moveTo(x - 5, y);
 | 
	
		
			
				|  |  | -                    ctx.lineTo(x, y + 3);
 | 
	
		
			
				|  |  | -                    ctx.lineTo(x - 5, y + 6);
 | 
	
		
			
				|  |  | -                } else {
 | 
	
		
			
				|  |  | -                    ctx.moveTo(x, y);
 | 
	
		
			
				|  |  | -                    ctx.lineTo(x, y + 5);
 | 
	
		
			
				|  |  | -                    ctx.lineTo(x - 5, y + 5);
 | 
	
		
			
				|  |  | +            let offset = 0;
 | 
	
		
			
				|  |  | +            let step = 7;
 | 
	
		
			
				|  |  | +            let level = getTreeLevel(datas[row],datas);//从0开始,取当前节点是第几级的
 | 
	
		
			
				|  |  | +            let tem = offset+margin+ rectW/2+step;//两条线之间的间隔
 | 
	
		
			
				|  |  | +            let t_offset = offset;
 | 
	
		
			
				|  |  | +            let temParentID = datas[row].ParentID;
 | 
	
		
			
				|  |  | +            for(let i = level;i>0;i--){//这里是画子节点前面的竖线,从第二级开始
 | 
	
		
			
				|  |  | +                let temParent = getParent(temParentID,datas);
 | 
	
		
			
				|  |  | +                if(temParent){//父节点有下一个兄弟节点才需要画
 | 
	
		
			
				|  |  | +                    if(hasNextBrother(parentMap,temParent)) sheetCommonObj.drawLine(ctx,x+t_offset+tem*i,y,x+t_offset+tem*i,y+h);
 | 
	
		
			
				|  |  | +                    temParentID = temParent.ParentID;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                ctx.fill();
 | 
	
		
			
				|  |  | -                ctx.restore();
 | 
	
		
			
				|  |  | +                offset +=tem;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            else {
 | 
	
		
			
				|  |  | -                ctx.save();
 | 
	
		
			
				|  |  | -                ctx.restore();
 | 
	
		
			
				|  |  | +            offset+=step;
 | 
	
		
			
				|  |  | +            if(hasChildern(datas[row].ID,datas)){//如果是有子节点
 | 
	
		
			
				|  |  | +                //第一条不用画方框头上那条竖线其它都要
 | 
	
		
			
				|  |  | +                if(row !=0) sheetCommonObj.drawLine(ctx,x+offset+ rectW/2+margin,y,x+offset+ rectW/2+margin,y + Math.round(h / 2) - rectH / 2);
 | 
	
		
			
				|  |  | +                //画方框下面的那条竖线,如果没有下一个兄弟节点,则不用画
 | 
	
		
			
				|  |  | +               if(hasNextBrother(parentMap,datas[row])) sheetCommonObj.drawLine(ctx,x+offset+ rectW/2+margin,y + Math.round(h / 2) + rectH / 2,x+offset+ rectW/2+margin,y + h);
 | 
	
		
			
				|  |  | +                sheetCommonObj.drowRect(ctx, x+offset, y, w, h,rectW,rectH,margin);
 | 
	
		
			
				|  |  | +                sheetCommonObj.drowSymbol(ctx, x+offset, y, w, h,rectW,rectH,margin, this.collapsed);
 | 
	
		
			
				|  |  | +                this.rectInfo = {x:x+offset+margin,rectW:rectW}//计录一下可点击位置
 | 
	
		
			
				|  |  | +            }else {
 | 
	
		
			
				|  |  | +                let hasNext = datas[row+1]?datas[row+1].ParentID == datas[row].ParentID:false;
 | 
	
		
			
				|  |  | +                sheetCommonObj.drowSubItem(ctx, x, y, w, h, offset,hasNext,margin+ rectW/2);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            offset += step;
 | 
	
		
			
				|  |  | +            offset += rectW;
 | 
	
		
			
				|  |  | +            x = x + offset;//设置偏移
 | 
	
		
			
				|  |  | +            w = w - offset;
 | 
	
		
			
				|  |  | +            GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  |          // override getHitInfo to allow cell type get mouse messages
 | 
	
		
			
				|  |  |          TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
 | 
	
	
		
			
				|  | @@ -272,16 +280,59 @@ var feeRateObject={
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
 | 
	
		
			
				|  |  | -            var level = hitinfo.sheet.rowOutlines.getLevel(hitinfo.row);
 | 
	
		
			
				|  |  | -            var hoffset = (level + 2) * 12 + hitinfo.cellRect.x;
 | 
	
		
			
				|  |  | -            if (level==-1&&hitinfo.x < hoffset && hitinfo.x > hoffset - 10) {
 | 
	
		
			
				|  |  | -                var collapsed = hitinfo.sheet.rowOutlines.isCollapsed(hitinfo.row + 1);
 | 
	
		
			
				|  |  | -                hitinfo.sheet.rowOutlines.setCollapsed(hitinfo.row, !collapsed);
 | 
	
		
			
				|  |  | +            if (!_.isEmpty(this.rectInfo)&&hitinfo.x < this.rectInfo.x+this.rectInfo.rectW && hitinfo.x > this.rectInfo.x) {
 | 
	
		
			
				|  |  | +                this.collapsed = !this.collapsed;
 | 
	
		
			
				|  |  | +                this.refreshChildrenVisible(hitinfo.sheet);
 | 
	
		
			
				|  |  |                  hitinfo.sheet.invalidateLayout();
 | 
	
		
			
				|  |  |                  hitinfo.sheet.repaint();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          };
 | 
	
		
			
				|  |  | +        TreeNodeCellType.prototype.refreshChildrenVisible = function (sheet) {
 | 
	
		
			
				|  |  | +            sheet.suspendPaint();
 | 
	
		
			
				|  |  | +            sheet.suspendEvent();
 | 
	
		
			
				|  |  | +            refreshVisible(datas[row]);
 | 
	
		
			
				|  |  | +            sheet.resumeEvent();
 | 
	
		
			
				|  |  | +            sheet.resumePaint();
 | 
	
		
			
				|  |  | +            function refreshVisible(item){
 | 
	
		
			
				|  |  | +                if(parentMap[item.ID]){
 | 
	
		
			
				|  |  | +                    for(let sub of parentMap[item.ID]){
 | 
	
		
			
				|  |  | +                        refreshVisible(sub)
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                let parent = getParent(item.ParentID,datas);
 | 
	
		
			
				|  |  | +                if(parent){
 | 
	
		
			
				|  |  | +                    let prow= datas.indexOf(parent);
 | 
	
		
			
				|  |  | +                    let visible = !sheet.getCellType(prow,0).collapsed;
 | 
	
		
			
				|  |  | +                    let trow = datas.indexOf(item);
 | 
	
		
			
				|  |  | +                    sheet.getRange(trow , -1, 1, -1).visible(visible);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  |          return new TreeNodeCellType()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        function getTreeLevel(item,data) {
 | 
	
		
			
				|  |  | +            if(item.ParentID){
 | 
	
		
			
				|  |  | +                 let pitem =  _.find(data,{'ID':item.ParentID});
 | 
	
		
			
				|  |  | +                 return  getTreeLevel(pitem,data) + 1;
 | 
	
		
			
				|  |  | +             }else {
 | 
	
		
			
				|  |  | +                 return 0
 | 
	
		
			
				|  |  | +             }
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  | +        function hasChildern(ID,data) {//返回是否有子项
 | 
	
		
			
				|  |  | +             let p = _.find(data,{'ParentID':ID});
 | 
	
		
			
				|  |  | +             if(p) return true;
 | 
	
		
			
				|  |  | +             return false
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  | +        function getParent(ParentID,data) {
 | 
	
		
			
				|  |  | +             let p = _.find(data,{'ID':ParentID});
 | 
	
		
			
				|  |  | +             return p;
 | 
	
		
			
				|  |  | +         }
 | 
	
		
			
				|  |  | +        function hasNextBrother(parentMap,item){
 | 
	
		
			
				|  |  | +            let children =parentMap[item.ParentID];
 | 
	
		
			
				|  |  | +            if(children && children.indexOf(item) == children.length -1) return false;
 | 
	
		
			
				|  |  | +            return true
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      getFeeRateEditCellType:function () {
 | 
	
		
			
				|  |  |          var ns = GC.Spread.Sheets;
 |