Browse Source

修改费率、费率选择页面树结构控件

zhangweicheng 6 năm trước cách đây
mục cha
commit
7f9e97d433

+ 62 - 1
public/web/sheet/sheet_common.js

@@ -739,6 +739,67 @@ var sheetCommonObj = {
             sheet.resumeEvent();
             sheet.resumePaint();
         }
+    },
+    drowRect:function (ctx, x, y, w, h,rectW,rectH,margin) {
+        ctx.save();
+        ctx.strokeStyle = "gray";
+        ctx.translate(0.5, 0.5);
+        ctx.beginPath();
+        let rectX = x + margin;
+        let rectY = y + Math.round(h / 2) - rectH / 2;
+        ctx.moveTo(rectX, rectY);
+        ctx.lineTo(rectX, rectY + rectH);
+        ctx.lineTo(rectX + rectW, rectY + rectH);
+        ctx.lineTo(rectX + rectW, rectY);
+        ctx.lineTo(rectX, rectY);
+        ctx.moveTo(rectX + rectW, y + Math.round(h / 2));
+        ctx.lineTo(rectX + rectW + 5, y + Math.round(h / 2));
+        ctx.stroke();
+        ctx.restore();
+    },
+    drawLine : function (ctx, x1, y1, x2, y2, color) {
+        let l_color = color?color:"gray";
+        ctx.save();
+        ctx.translate(0.5, 0.5);
+        ctx.beginPath();
+        ctx.moveTo(x1, y1);
+        ctx.lineTo(x2, y2);
+        ctx.strokeStyle = l_color;
+        ctx.stroke();
+        ctx.restore();
+    },
+    drowSymbol :function (ctx, x, y, w, h,rectW,rectH,margin,collapsed) {
+        ctx.save();
+        ctx.strokeStyle = "#000000";
+        ctx.translate(0.5, 0.5);
+        ctx.beginPath();
+        ctx.moveTo(x + margin + 2, y + Math.round(h / 2));
+        ctx.lineTo(x + margin + 8, y + Math.round(h / 2));
+        let rectY = y + Math.round(h / 2) - rectH / 2;
+        if (collapsed) {
+            ctx.moveTo(x + margin + rectW / 2, rectY + 2);
+            ctx.lineTo(x + margin + rectW / 2, rectY + 2 + 6);
+        }
+        ctx.stroke();
+        ctx.restore();
+    },
+    drowSubItem: function (ctx, x, y, w, h, offset, hasNext,step) {
+        let t_step = step?step:6;
+        offset += t_step;
+        ctx.save();
+        ctx.strokeStyle = "gray";
+        ctx.translate(0.5, 0.5);
+        ctx.beginPath();
+        ctx.moveTo(x + offset, y);
+        ctx.lineTo(x + offset, y + Math.round(h / 2));
+        offset += 9;
+        ctx.lineTo(x + offset, y + Math.round(h / 2));
+        if (hasNext) {
+            ctx.moveTo(x + offset - 9, y + Math.round(h / 2));
+            ctx.lineTo(x + offset - 9, y + h);
+        }
+        ctx.stroke();
+        ctx.restore();
+        return offset;
     }
-
 }

+ 4 - 0
public/web/tree_sheet/tree_sheet_controller.js

@@ -74,6 +74,10 @@ var TREE_SHEET_CONTROLLER = {
                             sels[0].row = beginRow;
                         }
                         that.sheet.deleteRows(sels[0].row, rowCount);
+                        if(sels[0].row >=  that.tree.items.length){
+                            sels[0].row = that.tree.items.length-1;
+                            sels[0].colCount = 1;
+                        }
                         that.setTreeSelected(that.tree.items[sels[0].row]);
                         that.sheet.setSelection(sels[0].row,sels[0].col,1,sels[0].colCount);
                     });

+ 101 - 50
web/building_saas/main/js/views/fee_rate_view.js

@@ -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;

+ 7 - 55
web/building_saas/main/js/views/glj_view.js

@@ -1280,56 +1280,6 @@ var gljOprObj = {
         function TreeNodeCellType() {
             this.ctx = null;
         }
-        function drowRect(ctx, x, y, w, h) {
-            ctx.save();
-            ctx.strokeStyle = "gray";
-            ctx.translate(0.5, 0.5);
-            ctx.beginPath();
-            let rectX = x + margin;
-            let rectY = y + Math.round(h / 2) - rectH / 2;
-            ctx.moveTo(rectX, rectY);
-            ctx.lineTo(rectX, rectY + rectH);
-            ctx.lineTo(rectX + rectW, rectY + rectH);
-            ctx.lineTo(rectX + rectW, rectY);
-            ctx.lineTo(rectX, rectY);
-            ctx.moveTo(rectX + rectW, y + Math.round(h / 2));
-            ctx.lineTo(rectX + rectW + 5, y + Math.round(h / 2));
-            ctx.stroke();
-            ctx.restore();
-        }
-        function drowSymbol(ctx, x, y, w, h, collapsed) {
-            ctx.save();
-            ctx.strokeStyle = "#000000";
-            ctx.translate(0.5, 0.5);
-            ctx.beginPath();
-            ctx.moveTo(x + margin + 2, y + Math.round(h / 2));
-            ctx.lineTo(x + margin + 8, y + Math.round(h / 2));
-            let rectY = y + Math.round(h / 2) - rectH / 2;
-            if (collapsed) {
-                ctx.moveTo(x + margin + rectW / 2, rectY + 2);
-                ctx.lineTo(x + margin + rectW / 2, rectY + 2 + 6);
-            }
-            ctx.stroke();
-            ctx.restore();
-        }
-        function drowSubItem(ctx, x, y, w, h, offset, nextItem) {
-            offset += 6;
-            ctx.save();
-            ctx.strokeStyle = "gray";
-            ctx.translate(0.5, 0.5);
-            ctx.beginPath();
-            ctx.moveTo(x + offset, y);
-            ctx.lineTo(x + offset, y + Math.round(h / 2));
-            offset += 9;
-            ctx.lineTo(x + offset, y + Math.round(h / 2));
-            if (nextItem && nextItem.isMixRatio) {
-                ctx.moveTo(x + offset - 9, y + Math.round(h / 2));
-                ctx.lineTo(x + offset - 9, y + h);
-            }
-            ctx.stroke();
-            ctx.restore();
-            return offset;
-        }
         TreeNodeCellType.prototype =  comboboxOptions?sheetCommonObj.getDynamicCombo():new ns.CellTypes.Text();
         TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
             this.ctx= ctx;
@@ -1345,11 +1295,12 @@ var gljOprObj = {
                 let offset = margin + rectW + 6;
                 let recode = data[options.row];
                 if (recode && recode.hasOwnProperty('subList')) {
-                    drowRect(ctx, x, y, w, h);
+                    sheetCommonObj.drowRect(ctx, x, y, w, h,rectW,rectH,margin);
                     let collapsed = recode.collapsed == undefined ? true : recode.collapsed;//options.sheet.getTag(options.row,options.col);
-                    drowSymbol(ctx, x, y, w, h, collapsed);
+                    sheetCommonObj.drowSymbol(ctx, x, y, w, h,rectW,rectH,margin, collapsed);
                 } else if (recode && recode.isMixRatio) {
-                    offset = drowSubItem(ctx, x, y, w, h, offset, data[options.row + 1]);
+                    let hasNext = data[options.row + 1] && data[options.row + 1].isMixRatio;
+                    offset = sheetCommonObj.drowSubItem(ctx, x, y, w, h, offset,hasNext);
                     offset += 1;
                 }
                 arguments[2] = x + offset;
@@ -1376,6 +1327,9 @@ var gljOprObj = {
         };
         TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
             let recode = data[hitinfo.row];
+            if(hitinfo.x < hitinfo.cellRect.x+hitinfo.cellRect.width -15){
+                hitinfo.sheet.setTag(hitinfo.row,hitinfo.col,"locked")//通过这个来控制除了点击下拉框的三角形,点击其它地方不充许进入编辑状态,不然不好控制下拉框超出页面后调整滚动条
+            }
             if (recode && recode.hasOwnProperty('subList')) {
                 let hoffset = hitinfo.cellRect.x + 3;
                 if (hitinfo.x > hoffset && hitinfo.x < hoffset + 10) {
@@ -1393,8 +1347,6 @@ var gljOprObj = {
                 hitinfo.sheet.setTag(hitinfo.row,hitinfo.col,"");
                 sheetCommonObj.scrollSheetForOption(hitinfo.sheet,this.ctx,hitinfo.cellRect,hitinfo.row,comboboxOptions);//下拉框超出显示后自动调整滚动条
                 GC.Spread.Sheets.CellTypes.ComboBox.prototype.processMouseDown.apply(this, arguments);
-            }else {
-                hitinfo.sheet.setTag(hitinfo.row,hitinfo.col,"locked")//通过这个来控制除了点击下拉框的三角形,点击其它地方不充许进入编辑状态,不然不好控制下拉框超出页面后调整滚动条
             }
         };
         let cellType = new TreeNodeCellType();