jackyrong

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

    一个struts1+spring+hibernate的典型权限系统的设计思路,归纳小结如下,特别适用于简单场合的,比如某个单位下,有直属单位及部门的

情况.数据表设计如下
user表:
  userid:
  username:
  unitid: //所属单位的id

  deptid://所属部门的id

   status:0表示为普通用户 1:表示为该单位的最高管理员

 

role角色表
  
  id:编号

  rolename:角色名
  content:角色的具体分配权限

   memo:备注
    unit:所属的单位id

userright表:(user与role是多对多,因此需要该表)
    id:
    userId:
    roleid:

 

unit表(单位表)
     unitId:单位编号
    unitName:单位名
     fatherId:上级单位ID (如果为0的时候,表示为最上层的单位)
    allFatherId:保存所有关联的父级单位的id路径)

   unitType :表明是单位还是部门,  0:单位, 1:部门
  

举个例子说明下:
     unitid   unitname    fatherid    allfatherid   unittype

        1       根单位              0                          0

        2      根单位部门1       1          ,1               1

        3      直属单位1           1        ,1                0

        4      直属单位1的部门1  3      ,1,3             1

 

AddressGroup  单位群组表:这个表的作用在于,可以将某几个单位归为一个群组,那么比如在发文的时候,可以一次同时发送文件给该群组下的
所有的单位
   groupId   群组编号:
   groupName   群组名称
   content:包含的单位id,比如某个群组有单位1,3的

 

二 在页面层中,类似如下:
      <td rowspan=4>发文管理</td>
      <td><input name="box" type="checkbox" value="211">发文登记</td>
      <td><input name="box" type="checkbox" value="212" >创建</td>
      <td><input name="box" type="checkbox" value="213" >修改</td>
      <td width=15%><input name="box" type="checkbox" value="215" >查看</td>

  .......就是很多个上面的形式,

然后用javascript把用户所选的都记录下来
   function check(){
  if (thisForm.roleName.value == ""||trim(thisForm.roleName.value)==""){
    alert("请填写角色名称!");
    thisForm.roleName.focus();
    return false;
  }
  thisForm.content.value=getRole();
  thisForm.submit();
}
//将角色用逗号连接起来
function getRole(){
  var allCHK = document.body.all.tags('INPUT');
  var lstr = "" ;
  for(i=0;i<allCHK.length;i++){
    if(allCHK[i].type.toUpperCase()=="CHECKBOX" && allCHK[i].checked==true){
       if (lstr==""){
          lstr = allCHK[i].value;}
       else {lstr= lstr + "," + allCHK[i].value;     }
     }
  }
  return lstr ;
}

同样要埋藏一个hidden域来保存咯
<input type=hidden name=content value="$!role.getContent()">

 

三 action层的保存
    /**
  * 保存角色信息
  */
 public void saveRole(Role role)throws Exception{
  String where = " from Role where roleName='"+role.getRoleName()+"' and unitId = "+role.getUnit().getUnitId()+" and roleId<>"+role.getRoleId();
  List list = roleDao.find(where);
  if(list.size()>0){
   throw new LogicException("本单位中已经存在" + role.getRoleName() + "这个角色");
  }
  roleDao.save(role);
 }

 

四 编辑角色时,把某个角色读取出来,回显在页面上
   public ActionForward viewRole(
  ActionMapping mapping,
  ActionForm form,
  HttpServletRequest request,
  HttpServletResponse response){
  String roleId = request.getParameter("roleId");
  if(!("".equals(roleId))){
   Role role = roleManager.getRole(roleId);
   request.setAttribute("role",role);
  }
  return mapping.findForward("viewRole");
 }

  

   在JSP页面中,可以读出来 ,可以在body的onload函数中,读init();

<input type=hidden name="content" value="$!role.getContent()">
   function init(){
 var allCHK = document.body.all.tags('INPUT');
 var content = thisForm.content.value;
 if(content != ""){
   var strIds = content.split(",");
   for(k=0;k<strIds.length;k++){
      for(i=0;i<allCHK.length;i++){
        if(allCHK[i].type.toUpperCase()=="CHECKBOX"  &&  allCHK[i].name=="box"  && allCHK[i].value==strIds[k]) {
           allCHK[i].checked=true ;
        }
      }
   }


 }
}

 

五  权限的判断
    一般在一个菜单里面,可以在导航菜单中予以体现
  下面是velocity的一个例子
    #set ($RECVDOC_LIST = 111)
#set ($RECVDOC_SIGN = 112)
#set ($RECVDOC_TUIHUI = 113)
#set ($RECVDOC_READ = 114)
#set ($RECVDOC_LOOKFOR = 115) 

   就是设定某些功能的权限编码

 然后是service层的,取出某个用户的权限:
    public  Vector getPermissionIDsByUserId(int userId) throws Exception{
    int i;
    Vector v=new Vector();
    String sql=" from Role where roleid in (select roleId from UsersRight where userId="+userId+")";
    List list = roleDao.find(sql);
    Iterator iter = list.iterator();
    while(iter.hasNext()){
     Role role = (Role)iter.next();
        String strIds[] = StringUtils.split(role.getContent(),",");
        for(i = 0; i < strIds.length; i++){
           v.add(strIds[i]);
        }
    }
    return v;
  }
}

 

public boolean  hasPermission(int permissionId) throws Exception{
      String permissionIdStr=Integer.toString(permissionId);
      boolean retValue = false;
      if(permission == null) {
      
       //返回该用户的权限
        permission = rmg.getPermissionIDsByUserId(u.getUserId().intValue());
      }
      if(permissionIdStr.length()==3){  retValue=permission.contains(permissionIdStr);}

 

      if(permissionIdStr.length()==1)
      {
          int i;
          for(i=0;i<permission.size();i++)
          {
              if (((String)permission.elementAt(i)).startsWith(permissionIdStr))
              {
                 retValue=true;
                 i=permission.size();
              }
          }
      }
      return retValue;
    }
   

 菜单拦的判断
  

 var p;
  #if($userinfo.hasPermission(1))
    p = new createPanel('recvdoc','收文管理');
    #if($userinfo.hasPermission($RECVDOC_SIGN_LIST) || $userinfo.hasPermission($RECVDOC_SIGN_PRINT) || $userinfo.hasPermission($RECVDOC_SIGN_READ) || $userinfo.hasPermission($RECVDOC_SIGN_LOOKFOR))
      p.addButton('$request.getContextPath()/menu/images/recvdoc.gif','待签收文件','changePage("10");');
    #end

 

   比如上面的收文管理模块中,有很多个子功能,这里首先传入到userinfo.hasPermission(1))去判断,

这时会执行if(permissionIdStr.length()==1)
      {
的判断,

   假如该用户有收文管理下的某个子功能的权限,比如111,则通过该验证(注意   i=permission.size();跳出FOR了,返回true值,因此该
用户可以看到"收文管理"这个大的菜单,至于该用户能具体看到下面的哪些子功能,则通过
    if(permissionIdStr.length()==3){  retValue=permission.contains(permissionIdStr);} 去判断了.

 

 

 

 

 

 

 

posted on 2008-10-22 12:33  jackyrong的世界  阅读(1236)  评论(0编辑  收藏  举报