扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
OA中用户角色权限问题
一个用户进入OA,我怎么知道他是普通员工,还是经理,还是总经理呢,然后对应用业务操作不同呢?比如说普通员工可以看到自己的数据,经理可以看到自己部门所有员工的,总经理不仅可以看到整个公司所有员工的,还可以对每位员工的数据进行删,改,查。
我现在又一个User表
UId UName DeptID(部门ID)
1 张三 1
2 李四 2
3 王五 2
4 赵六 3
5 赵七 3
部门表:Dept
DId DName DParentID(父节点ID)
1 总经办 0
2 销售部 0
3 人事部 0
最终的树形展示:
总经办
|________张三(总经理)
|
销售部
|________李四 (部门经理)
|
|________王五(普通员工)
|
销售部
|________赵六 (部门经理)
|
|________赵七(普通员工)
可能有人会说,我可以再添加一个角色表(Role)
RoleID RoleName
1 总经理
2 部门经理
3 普通员工
这样虽然有了个角色概念,用1,2,3代表不同的角色,那难道让我在程序里判断if(角色ID=="1")...那如果这个公司又增加了一个新的角色,比如说:秘书,用4表示,那我对应整套OA只要是设计的权限部门的都要再加一个判断,判断是否等于4吗?这些我觉得是不可行的。
可能是我的思路问题,但是我不知道像这样的系统,是怎么处理权限的问题的,根据不同的角色,进行不同权限的业务逻辑。
我看了,网上免费的OA系统,他好像是给Role分配功能权限,意思就是比如说这个OA系统有三个功能,新闻发布,新闻查看,新闻管理,然后他根据不同的角色,比如说让总经理都有这些功能,让普通员工只有新闻查看的这个功能。虽然这样的做法在一定程度上解决了权限的问题,但是如果 “新闻管理”这个功能,所有角色都应该有这个功能,不同的是,不同角色看到的信息是不一样的,比如说总经理就看到所有人的,并且可以删,经理看到自己本部门的,员工只能看自己的。这个时候我就没法知道他到底是部门经理呢?还是什么呢?
加角色表,角色表后加权限表。权限控制只针对权限表编程。用户进入后,取角色,取权限,最后用户能实现的操作由取得的权限来确定。
加一个权限表就行了,用户登陆,根据用户ID,去取权限.
基于角色的权限管理
http://www.cnblogs.com/badboy2008/articles/579633.html
-----------------------------------------------------------------
典型的简单权限分配系统方法介绍
[url=http://www.cnblogs.com/jackyrong/archive/2008/10/22/1316645.html[/url]
一个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);} 去判断了.
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者