zoukankan      html  css  js  c++  java
  • [转]extjs 的权限问题。要求控制的对象是 菜单,按钮,URL

    这两天在解决extjs 的权限问题。要求控制的对象是  菜单,按钮,URL

    解题思路1 : 重载Connection类

     由于extjs和server端交互全都是 json格式的数据交互,server端不会控制页面的跳转,页面跳转,提示功能全都有extjs来完成。

       extjs和server端的交互方法全都是继承自 Ext.data.Connection,这个类中可以拦截所有和server端交互的方法。

       server端的权限控制用acegi做的,如果没通过acegi的验证,没有授权会返回到403.jsp,需要重登录会返回到 login.jsp。

       因此重载Connection类,并改写其中的 handleResponse 方法,判断返回的结果是否是 403.jsp,login.jsp, 如果是就进行相应的控制,如果是正常的返回数据就继续向下执行。

         我个人在403.jsp  和login.jsp 的第一行加上了 注释代码<!--权限控制自定义关键字-->,就是靠这个关键字来工作的

       ,代码如下:

     //此处重载了Cunnection方法,用来拦截client与Server的交 互,
    //后台acegi拦截用户请求后,如果无权限,返回403.jsp;如果没登录,返回login.jsp;
    //通过Acegi拦截 后,才返回用户想要的Json结果
    Ext.override(Ext.data.Connection, {  
                handleResponse : Ext.data.Connection.prototype.handleResponse.createInterceptor(  
             function(response) {  
                 var resText=response.responseText;
            if (resText.length>10) {
               resText=resText.substr(0,9);
            }  
            if (resText=='<!--login'){
                window.top.location.href = topURL+"/login.jsp";
             } else if (resText=='<!--deny-'){
              if (resText=='<!--deny-'){
                  Ext.Msg.show({
           title : '错误提示',
           msg : '禁止访问此功能,请和系统管理员联系',
           buttons : Ext.Msg.OK,
           icon : Ext.Msg.INFO
            });
              };   
             } else if (resText=='<!--404--'){
                  Ext.Msg.show({
           title : '错误提示',
           msg : '页面未找到',
           buttons : Ext.Msg.OK,
           icon : Ext.Msg.INFO
            });
             }
            })  
    });

    解题思路2: server端返回菜单json数据

       我的菜单用tree来做的,在初始化主页面时先初始化菜单,

             loader : new Ext.tree.TreeLoader({
              dataUrl : 'getJsonMenus.do'
           }),

           这个'getJsonMenus.do'返回菜单json数据,在strut2中的配置为:

        <action name="getJsonMenus" class="jsonSystemAction" method="getJsonMenus">
       <result type="json">
        <param name="root">menus</param>
       </result>
      </action>

    menus是个list<JsonMenu>,

      JsonMenu的属性为:

     private String text;
     private boolean expanded;
     private String id;
     private boolean leaf;
     private List<JsonMenu> children;

     

           getJsonMenus.do 返回的格式是可以满足tree的格式要求的。

          js代码如下

    Ext.onReady(function() {
     setTimeout(function() {
      Ext.get('loading').remove();
      Ext.getDom('header').style.visibility = 'visible';
      var vp = new Ext.Viewport({
       layout : 'border',
       defaults : {
        collapsible : true,
        split : true
       },
       items : [{
        xtype : 'box',
        region : 'north',
        applyTo : 'header',
        height : 30,
        split : false
       }, {
        title : currentUser,
        id : 'accordion-panel',
        layout : 'border',
        region : 'west',
        margins : '2 0 5 5',
        width : 200,
        minSize : 200,
        maxSize : 250,
        bodyStyle : 'background-color:#DFE8F6',
        defaults : {
         border : false
        },
        bbar : [{
         text : '开始',
         iconCls : 'icon-plugin',
         menu : new Ext.menu.Menu({
          items : [{
           text : '关于系统',
           iconCls : 'icon-info',
           handler : function() {
            new Ext.Window({
             closeAction : 'close',
             resizable : false,
             bodyStyle : 'padding: 7',
             modal : true,
             title : '关于本系统',
             html : '本系统采用目前较为流行的技术实现,<br>前台使用了ExtJs技术,所以实现了跨浏览器<br>' +
               ' 本程序在IE6,IE7,FireFox3均测试通过!<br><br>主要技术: Struts2 + Spring + iBatis + ExtJs<br><br>'
               + '数&nbsp;&nbsp;据&nbsp;&nbsp;库: Oracle 9i',
             width : 300,
             height : 200
            }).show();
           }
          }, {
           text : '退出系统',
           iconCls : 'icon-delete',
           handler : function() {
            Ext.Msg.confirm('操作提示', '您确定要退出本系统?', function(btn) {
             if ('yes' == btn) {
              Ext.Ajax.request({
               url : 'logout.do',
               success : function() {
                location = '/';
               },
               failure : function() {
                Ext.Msg.show({
                 title : '错误提示',
                 msg : '退出系统失败!',
                 icon : Ext.Msg.ERROR,
                 buttons : Ext.Msg.OK
                });
               }
              });
             }
            });
           }
          }]
         })
        }],
        items : [{
         layout : 'accordion',
         region : 'center',
         items : [{
          title : '导航菜单',
          iconCls : 'icon-nav',
          border : false,
          items : [{
           xtype : 'treepanel',
           border : false,
           rootVisible : false,
           autoScroll : true,
           loader : new Ext.tree.TreeLoader({
              dataUrl : 'getJsonMenus.do'
           }),
           root : new Ext.tree.AsyncTreeNode(),
           listeners : {
            'click' : function(n) {
             try {
              var sn = this.selModel.selNode || {};
              if (n.leaf && n.id != sn.id) {
               Ext.getCmp('content-panel').layout.setActiveItem(n.id.substring(0, n.id
                 .indexOf('-'))
                 + '-panel');
              }
             } catch (e) {
             }
            }
           }
          }]
         },{
             title : '系统设置',
          iconCls : 'icon-nav'
         }]
        }]
       }, {
        id : 'content-panel',
        region : 'center',
        layout : 'card',
        margins : '2 5 5 0',
        activeItem : 0,
        border : false,
        items : [start, p_company, p_user, p_dept, p_system, p_subject, p_category, p_resource]
       }]
      });
     }, 250);
     
    });

     

       这样就得到了菜单,还有网友提出了异步菜单解决方法,我也把它列到下面

              

    解题思路3 : 同步加载所有的TAG,用hidden属性控制显示   

         所有的tag必须要同步加载后才可以控制component的hidden属性,异步加载不好用。

          同步加载的方法如下:

            //FUTURE_TAG全局的TAG控制类, 控制的组件的hidden属性,key=TAG的名字,value=true(组件隐藏),false(组件显示)
             var FUTURE_TAG={tbar1: false, tbar2: true};

    var conn = Ext.lib.Ajax.getConnectionObject().conn;  
    conn.open("GET", 'getJsonTags.do',false);  
    conn.send(null);  
    future_tag= eval('(' + conn.responseText + ')');

     

    在js中TAG的用法如下:

    var btn_add_system = new Ext.Button({
     text : '添加',
     iconCls : 'icon-add',
     hidden: FUTURE_TAG.system_add,
     handler : function() {
      window_add_system.show();
     }
    });

     

    getJsonTags.do 返回一个Map对象,key是TAG名字,value是boolean

     java的写法如下:

    tagMap=new HashMap<String,Boolean>();
      for (int i=0;i<allTagList.size();i++){
       tagMap.put(allTagList.get(i).getResString(), true);
      }

     

    strut2配置如下:

      <action name="getJsonTags" class="jsonSystemAction" method="getJsonTags">
       <result type="json">
        <param name="root">tagMap</param>
       </result>
      </action>

     

    这样就可以在后台控制前台的组件是否显示了,从而达到了我们的目的。

     解决思路4:

    通过ajax读取服务器端的权限值,返回这样的数据:
    {tbar1: false, tbar2: true}
    然后在extjs中:
    var vResult = eval('(' + ajaxText + ')'); //得到{tbar1: false, tbar2: true}
    这样就可以直接给tbar赋值了
    disabled: vResult.tbar1
    disabled: vResult.tbar2  

     解决思路5:

     设置模块权限用于设置用户可以操作的权限。允许设置用户对模块的可操作与不可操作。

     

     

    弹出设置权限子窗体

     

    设置权限之前须选择一个用户。

     
    Js代码

        var row = grid_user.getSelectionModel().getSelected();         
                  if(!row){   
                      alert('对不起,您还未选择数据!');   
                      return;   
                  }   

    var row = grid_user.getSelectionModel().getSelected();                  if(!row){                alert('对不起,您还未选择数据!');              return;          }    

     

    创建一棵树,树放置在弹出窗体的中央。

     
    Js代码

       1. var root=new Ext.tree.TreeNode({   
       2.                 id:"root",   
       3.                 text:"所有操作",   
       4.                 checked:false,   
       5.                 iconCls:'task-folder'  
       6.           });   
       7.              
       8.           var tree=new Ext.tree.TreePanel({   
       9.             frame:false,   
      10.             region:'center',   
      11.             root:root,   
      12.             animate:true,   
      13.             enableDD:false,   
      14.             border:false,   
      15.             rootVisible:true,   
      16.             autoScroll:true  
      17.          });  

    var root=new Ext.tree.TreeNode({                id:"root",                text:"所有操作",                checked:false,                iconCls:'task-folder'          });                    var tree=new Ext.tree.TreePanel({            frame:false,            region:'center',            root:root,            animate:true,            enableDD:false,            border:false,            rootVisible:true,            autoScroll:true         });

     

    创建弹出子窗体。

     
    Js代码

       1. var win = new Ext.Window({   
       2.             title:'设置模块权限',   
       3.             closable:true,   
       4.             300,   
       5.             height:500,   
       6.             plain:true,   
       7.             layout:'border',   
       8.             modal:true,   
       9.             items:[tree]   
      10.         });   
      11.         win.show(this);  

    var win = new Ext.Window({            title:'设置模块权限',            closable:true,            300,            height:500,            plain:true,            layout:'border',            modal:true,            items:[tree]        });        win.show(this);

     

    在加载数据期间,给予提示。

     
    Js代码

       1. Ext.MessageBox.show({   
       2.             title:'请稍候',   
       3.             msg:'正在加载数据,请耐心等待...',   
       4.             progress:true              
       5.         });  

    Ext.MessageBox.show({            title:'请稍候',            msg:'正在加载数据,请耐心等待...',            progress:true                   });

     

    将根节点,所选择的用户行,父节点标志作为参数调用方法。

     
    Js代码

        getNodes(row,root,'root');  

    getNodes(row,root,'root');

     

     

    从后台中取得数据并以树形式在客户端展现

     

    方法定义与方法内容。

     
    Js代码

        function getNodes(row,root,parent){   
               //...   
        }  

    function getNodes(row,root,parent){       //...}

     

    JSON 数据的定义。

     
    Js代码

        var record_pri = new Ext.data.Record.create([   
                           {name:'modelId'},   
                           {name:'modelName'},   
                           {name:'sort'},   
                           {name:'canUse'},   
                           {name:'privilegeId'}   
                       ]);   
               var store_pri = new Ext.data.Store({   
                   proxy: new Ext.data.HttpProxy({url:'../'}),   
                   reader: new Ext.data.JsonReader({root:'rows'},record_pri)   
              });  

    var record_pri = new Ext.data.Record.create([                    {name:'modelId'},                    {name:'modelName'},                    {name:'sort'},                    {name:'canUse'},                    {name:'privilegeId'}                ]);        var store_pri = new Ext.data.Store({            proxy: new Ext.data.HttpProxy({url:'../'}),            reader: new Ext.data.JsonReader({root:'rows'},record_pri)        });

     

    无刷新请求,获取数据并展现出来;并添加事件监听。当点击树某一节点时,判断是否已经从后台取得数据,如果还没有取则从后台获取数据,再根据返回的数据判断是叶子节点还是非叶子节点。然后以不同的方式展现与处理。

     

    叶子节点和非叶子节点展现时,使用的图标不同。叶子节点没有添加单击事件,而非叶子节点添加了单击事件。

     
    Js代码

       1. Ext.Ajax.request({   
       2.             url:'http://www.cnblogs.com/../privilegeAction.do?method=list',   
       3.             params:{   
       4.                 userId:row.get('userId'),   
       5.                 parentId:parent   
       6.             },   
       7.             success:function(response, request){   
       8.                 Ext.MessageBox.hide();   
       9.                 var res = Ext.util.JSON.decode(response.responseText);   
      10.                 store_pri.loadData(res);   
      11.                 for(var i=0;i<store_pri.getCount();i++){   
      12.                     var rec = store_pri.getAt(i);   
      13.                     var canuse = (rec.get('canUse')=='是'?true:false);          
      14.                     var modid = rec.get('privilegeId') + '-id-' + rec.get('modelId');   
      15.                     var node;   
      16.                     if(rec.get('sort')=='菜单'){   
      17.                         node = new Ext.tree.TreeNode({   
      18.                             text:rec.get('modelName'),   
      19.                             id:modid,   
      20.                             checked:canuse,   
      21.                             iconCls:'task-folder'  
      22.                         });   
      23.                         node.on('click',function(node){   
      24.                             if(node.firstChild==null){   
      25.                                 getNodes(row,node,get_mod_id(node.id));   
      26.                              }   
      27.                         });   
      28.                     } else {   
      29.                         node = new Ext.tree.TreeNode({   
      30.                             text:rec.get('modelName'),   
      31.                             id:modid,   
      32.                             checked:canuse,   
      33.                             iconCls:'task'  
      34.                         });   
      35.                     }   
      36.                     node.on('checkchange',function(node,check){   
      37.                         Ext.Ajax.request({   
      38.                             url:'http://www.cnblogs.com/../privilegeAction.do?method=save2',   
      39.                             params:{   
      40.                                 privilegeId:get_rec_id(node.id),   
      41.                                 canuse:(check?'是':'否')   
      42.                             },   
      43.                             success:function(response, request){   
      44.                                
      45.                             },   
      46.                             failure:function(){   
      47.                                 Ext.MessageBox.hide();   
      48.                                 alert('sorry!');   
      49.                             }   
      50.                         });        
      51.                     });   
      52.                     root.appendChild(node);   
      53.                 }   
      54.                 root.expand();   
      55.             },   
      56.             failure:function(){   
      57.                 Ext.MessageBox.hide();   
      58.                 alert('sorry!');   
      59.             }   
      60.         });       

    Ext.Ajax.request({            url:'http://www.cnblogs.com/../privilegeAction.do?method=list',            params:{                userId:row.get('userId'),                parentId:parent            },            success:function(response, request){                Ext.MessageBox.hide();                var res = Ext.util.JSON.decode(response.responseText);                store_pri.loadData(res);                for(var i=0;i<store_pri.getCount();i++){                    var rec = store_pri.getAt(i);                    var canuse = (rec.get('canUse')=='是'?true:false);                            var modid = rec.get('privilegeId') + '-id-' + rec.get('modelId');                    var node;                    if(rec.get('sort')=='菜单'){                        node = new Ext.tree.TreeNode({                            text:rec.get('modelName'),                            id:modid,                            checked:canuse,                            iconCls:'task-folder'                        });                        node.on('click',function(node){                            if(node.firstChild==null){                                 getNodes(row,node,get_mod_id(node.id));                             }                        });                    } else {                        node = new Ext.tree.TreeNode({                            text:rec.get('modelName'),                            id:modid,                            checked:canuse,                            iconCls:'task'                        });                    }                    node.on('checkchange',function(node,check){                        Ext.Ajax.request({                            url:'http://www.cnblogs.com/../privilegeAction.do?method=save2',                            params:{                                privilegeId:get_rec_id(node.id),                                canuse:(check?'是':'否')                            },                            success:function(response, request){                                                        },                            failure:function(){                                Ext.MessageBox.hide();                                alert('sorry!');                            }                        });                         });                    root.appendChild(node);                }                root.expand();            },            failure:function(){                Ext.MessageBox.hide();                alert('sorry!');            }        });     

     

    当非叶子节点被点击时,递归地调用方法来获取孩子节点。

     

    获取行的ID和模块的ID。树的节点将行的ID和模块的ID一起取出来了。不然的话,如果只取得模块ID,而不取行ID,那么在修改的时候,则不能进行正确的修改。

     
    Js代码

        function get_rec_id(str){   
                var arr = str.split('-id-');   
                return arr[0];   
            }   
            function get_mod_id(str){   
                var arr = str.split('-id-');   
                return arr[1];   
           } 

  • 相关阅读:
    多测师讲解html _表格标签007_高级讲师肖sir
    多测师讲解 ---面试课程之项目(201)---高级讲师肖sir
    多测师讲解——项目流程和注意事项——高级讲师肖sir
    前端 HTML body标签相关内容 常用标签 超链接标签 a标签
    前端 HTML body标签相关内容 常用标签 定义列表<dl>
    前端 HTML body标签相关内容 常用标签 列表标签 ul,ol,li
    前端 HTML 标签里 特殊符号
    前端 HTML body标签相关内容 常用标签 分割线 <hr>
    前端 HTML body标签相关内容 常用标签 盒子标签 div
    前端 HTML body标签相关内容 常用标签 段落标签 p标签
  • 原文地址:https://www.cnblogs.com/chillsrc/p/1681406.html
Copyright © 2011-2022 走看看