实现角色权限叠加的原因:
最近在做一个项目,我是负责权限的管理,通过“权限->角色->员工”的方式来把权限赋给员工的,在新建角色时,我原来只是新建一个新的空角色,即这个角色是没有任何权限在里面,要通过管理员赋权限给这个角色,这个角色才有相应的权限。强哥说,这样做不太好,用户体验不太好,要实现角色叠加的功能。。。
什么是角色叠加?
角色叠加就是把源角色的权限赋给目标角色,如果目标角色已有相应的权限则判断目标角色的权限等级是否低于源角色的权限等级,若是,则修改目标角色的权限等级。
角色权限叠加相关的表的设置:主要有两个表,一个是页面关系表,记录角色拥有权限的页面及页面的权限的等级,两是每个关系功能键表,记录关系功能键的权限。这两个表是以关系ID来作关系的。(以确定角色页面的功能键)
角色叠加的功能设计思路:
1、页面权限叠加
2、页面功能权限叠加
其流程图为:
页面功能权限叠加流程:
功能键权限叠加流程:
存储过程具体实现:
数据库表的准备:
CREATE TABLE [dbo].[PV_tRoleToPage] (
[iID] int,
[iRelationID] int NOT NULL,
[iRoleID] int NOT NULL,
[iPageID] int NOT NULL,
[iFuncLevel] int NOT NULL,
[b] int
)
CREATE TABLE [dbo].[PV_tRelationToFunc] (
[iID] int NOT NULL,
[iRelationID] int NOT NULL,
[iFuncID] int NOT NULL,
[iFuncLevel] int NOT NULL,
[a] int,
[b] int
)
存储过程:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
--------这个存储过程是为了实现角色叠加,即把源角色的权限赋给目标角色
--------如果目标角色已拥有了这个权限则判断该权限的等级是否是小于源角色的权限,如果是则修改目标角色权限的等级
ALTER PROCEDURE [dbo].[PV_addRoleAuthority_new]
@iRoleIDsrc int ,--表示源角色
@iRoleIDdes int --表示目标角色(把目标角色里的权限赋给源角色)
AS
BEGIN
------------------------------循环遍历时用到,临时的变量-----------------------------
declare @icount int--记录表的数据条数
declare @jcount int--记录表的数据条数
declare @i int --遍历计数
declare @j int --遍历计数
declare @iRelationIDsrc int--记录源关系的ID
declare @iRelationIDdes int--记录目标关系的ID
declare @iFuncLevelsrc int--记录源等级值
declare @iFuncLeveldes int--记录目标等级值
declare @iPageID int --记录当前的页面ID
declare @iFuncID int --记录当前的功能键ID
---------------------------------创建临时表来存放源角色的信息---------------------------
if object_id('Tempdb.dbo.#src_iRelation') is not null--源角色页面关系ID与目标角色页面关系ID对应的表
drop table #src_iRelation
if object_id('Tempdb.dbo.#src_Func') is not null--功能权限键表
drop table #src_Func
if object_id('empdb.dbo.#src_RoleToPage') is not null--页面权限表
drop table #src_RoleToPage
create table #src_iRelation---临时表,存储源角色的所有页面所对应的关系ID
(
user_id int primary key identity(1,1),
iRelationIDsrc int,
iRelationIDdes int
)
create table #src_Func--临时表存储源角色当前页面所对应的功能键
(
user_id int primary key identity(1,1),
iID int,
iRelationID int,
iFuncID int,
iFuncLevel int,
a int,
b int
)
create table #src_RoleToPage---临时表存储源角色页面信息
(
user_id int primary key identity(1,1),
iID int,
iRelationID int,
iRoleID int,
iPageID int,
iFuncLevel int,
b int
)
------------------------------------------------------------------------------------------
--源角色页面权限信息加入到表#src_RoleToPage中~
insert into #src_RoleToPage(iPageID,iRoleID,iFuncLevel) select iPageID,iRoleID,iFuncLevel from PV_tRoleToPage
where iRoleID=@iRoleIDsrc
set @icount=(select count(*) from #src_RoleToPage)--源角色页面表中的记录条数
set @i=1
while (@i<=@icount)
begin
--获取当前页面ID
set @iPageID=(select iPageID from #src_RoleToPage where user_id=@i);
--如果目标角色没有目前页面的权限,直接为目标角色增加这个页面的权限
if((select count(*) from PV_tRoleToPage where iRoleID=@iRoleIDdes and iPageID=@iPageID)=0)
begin
insert into PV_tRoleToPage(iPageID,iRoleID,iFuncLevel) select iPageID,@iRoleIDdes,iFuncLevel from #src_RoleToPage where user_id =@i
end
--如果目标角色拥有目前页面的权限,则判断这个目标角色该页面的权限等级是否低于源角色该页面的权限等级,如果是,则修改等级
else
begin
set @iFuncLeveldes=(select iFuncLevel from PV_tRoleToPage where iRoleID=@iRoleIDdes AND iPageID=@iPageID)
set @iFuncLevelsrc=(select iFuncLevel from #src_RoleToPage where user_id =@i)
if(@iFuncLeveldes<@iFuncLevelsrc)
begin
Update PV_tRoleToPage set iFunclevel=@iFuncLevelsrc where iPageID=@iPageID and iRoleID=@iRoleIDdes
end
end
set @i=(@i+1)
end
--增加具体功能键权限
----------------------------------------------------------------------------------------------
insert into #src_iRelation (iRelationIDsrc,iRelationIDdes) select a.iRelationID , b.iRelationID FROM PV_tRoleToPage as a,PV_tRoleToPage as b
WHERE a.iRoleID=@iRoleIDsrc and b.iRoleID=@iRoleIDdes and a.iPageID=b.iPageID---源角色页面关系ID与目标角色页面关系ID关系加到临时表中
---------------遍历源角色的所有的页面,把当前页面源角色有的功能赋给目标角色-------------------
set @icount=(select count(*) from #src_iRelation)
set @i=1
while (@i<=@icount)
begin
set @iRelationIDsrc=(select iRelationIDsrc FROM #src_iRelation where user_id =@i)
set @iRelationIDdes=(select iRelationIDdes FROM #src_iRelation where user_id =@i)
--把之前#src_Func中的记录删除
truncate table #src_Func
--找到源角色当前页面ID的功能点权限,增加新的记录在#src_Func
insert into #src_Func (iRelationID,iFuncID,iFuncLevel,a,b) select iRelationID,iFuncID,iFuncLevel,a,b from PV_tRelationToFunc where iRelationID=@iRelationIDsrc
SELECT * FROM #src_Func
set @jcount =(select count(*) from #src_Func)
set @j=1
while(@j<=@jcount)
begin
--获得当前功能点的ID
set @iFuncID=(select iFuncID from #src_Func where user_id=@j)
--如果目标角色没有当前功能点ID的,直接把源角色当前功能点ID赋给它
if((select count(*) from PV_tRelationToFunc where iFuncID=@iFuncID and iRelationID=@iRelationIDdes)=0)
begin
insert into PV_tRelationToFunc (iRelationID,iFuncID,iFuncLevel,a,b) select @iRelationIDdes,iFuncID,iFuncLevel,a,b from #src_Func where user_id=@j
end
--如果不是的话,判断是否源角色当前功能点权限等级比目标角色的高,如果是,则修改目标角色等级
else
begin
set @iFuncLevelsrc=(select iFuncLevel from #src_Func where user_id=@j)
set @iFuncLeveldes=(select iFuncLevel from PV_tRelationToFunc where iFuncID=@iFuncID and iRelationID=@iRelationIDdes)
if(@iFuncLevelsrc>@iFuncLeveldes)
begin
update PV_tRelationToFunc set iFuncLevel=@iFuncLevelsrc where iFuncID=@iFuncID and iRelationID=@iRelationIDdes
end
end
set @j=@j+1
end
set @i=(@i+1)
end
-----------------------------------------------------------------------------------------------
---把功能信息加入到关系功能表中!
insert into PV_tRelationToFunc select iRelationID,iFuncID,iFuncLevel,a,b from #src_Func
-----------------------------------------删除临时表--------------------------------------------
drop table #src_iRelation
drop table #src_Func
END
在这个存储过程中我们需要注意的是:
1、在清空表 #src_Func中用到的是truncate table #src_Func ,清空表,并且usre_id置位从1开始
2、建立临时表后要把它们删除掉,因为这些表我们在下次到的时候可以再建立,不用占掉空间,而且表中的数据我们下次不用 用到。
由于今晚时间问题,写得比较粗糙,等下次有时间再来完善~