用户
 找回密码
 入住 CI 中国社区
搜索
查看: 4174|回复: 0
收起左侧

分享实现系统数据权限管理的过程

[复制链接]
发表于 2011-12-29 22:52:37 | 显示全部楼层 |阅读模式
最近用CI实现公司一个MIS的过程中,碰到一个数据权限管理问题。郁闷了好一阵。
最后追踪 金蝶 k3 的权限管理 sql。找到了解决办法。现在我把我的思路贴上来供大家参考。

问题描述:
    实现和ERP类似的对基础资料的查看,编辑,删除权限控制。 我用的 sql server 2005

(一)先贴上 k3 数据库跟踪的代码

SQL复制代码
 
-- 查询数据
SELECT t1.FItemID,MIN(t1.FParentIDX) AS FParentIDX
,(CASE WHEN MAX(SUBSTRING(t1.FdataAccessDelete,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END) AS FDeleteAccess
,(CASE WHEN MAX(SUBSTRING(t1.FDataAccessEdit,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END ) AS FEditAccess
,(CASE WHEN MAX(SUBSTRING(t1.FDataAccessView,t0.FaccessUUID/8+1,1) & POWER(2,7-(t0.FaccessUUID+7)%8))>0 THEN 1 ELSE 0 END) AS FViewAccess
FROM t_user t0 INNER JOIN Access_t_ICItem t1
ON t0.FuserID=16417 --16417用户ID
GROUP BY t1.FItemID
 
-- 修改数据
UPDATE Access_t_Organization SET FDataAccessView=
SUBSTRING(FDataAccessView,1,11)+CONVERT(BINARY(1),SUBSTRING(FDataAccessView,12,1) & 239)+SUBSTRING(FDataAccessView,13,88)
WHERE FParentIDX=25263 OR FItemID=25263
 
 
复制代码


(二)原理测试sql

SQL复制代码
 
--select power( 2,7-(@id+7)%8 )                                 -- power( 2,7-(@id+7)%8 ) 数据存放在字节的哪一位    
--select substring( @accesssetting,@id/8+1,1 )  -- ( @id/8+1 ) 数据存放在哪个字节
 
DECLARE @id AS INT                                                      SET @id = 5
-- 假设用户的 id =5
DECLARE @accesssetting AS BINARY(200)           SET @accesssetting = CONVERT(BINARY(200),0)
-- 假设基础资料存放权限的字段为  200 字节(支持 200 * 8 为用户)
-- 且默认所有人都没有权限 (全 0 )
 
-- 查询用户的权限,值为 0 没有权限
SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
-- 修改用户 id 的权限
-- 通过 用户id 和 权限字段的位数计算出 用户权限存放字节的前后区间
DECLARE @start_1 AS INT,@offset_1 AS INT,@start_2 AS INT, @offset_2 AS INT
SELECT @start_1         = CASE WHEN ( @id/8+1 ) > 1 THEN 1 ELSE 0 END
SELECT @offset_1        = CASE WHEN ( @id/8+1 ) > 1 THEN ( @id/8+1 ) - 1 ELSE 0 END
SELECT @start_2         = CASE WHEN ( @id/8+1 ) < 200 THEN ( @id/8+1 ) + 1 ELSE 0 END
SELECT @offset_2        = CASE WHEN ( @id/8+1 ) < 200 THEN 200 - ( @id/8+1 ) ELSE 0 END
-- select @start_1,@offset_1,@start_2,@offset_2
 
-- 授予用户权限(  |  位或操作符, power 求平方 )
SELECT @accesssetting = SUBSTRING( @accesssetting,@start_1,@offset_1 )
        + CONVERT( BINARY(1),SUBSTRING(@accesssetting, @id/8+1 ,1) | POWER(2,7-(@id+7)%8))
        + SUBSTRING(@accesssetting,@start_2,@offset_2)
 
-- 可以看到,值为8 有权限
SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
-- 取消用户权限(  ~  位非操作符 )
SELECT @accesssetting = SUBSTRING( @accesssetting,@start_1,@offset_1 )
        + CONVERT( BINARY(1),SUBSTRING(@accesssetting, @id/8+1 ,1) & ( ~ POWER(2,7-(@id+7)%8) ) )
        + SUBSTRING(@accesssetting,@start_2,@offset_2)
 
-- 好咯,权限已取消
SELECT SUBSTRING( @accesssetting,@id/8+1,1 ) & POWER(2,7-(@id+7)%8)
 
 
 
复制代码




本版积分规则